Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH 07/10] dt-bindings: iio: dac: add bindings doc for AD9739A
From: Rob Herring @ 2024-04-01 14:02 UTC (permalink / raw)
  To: Nuno Sa
  Cc: linux-iio, devicetree, Dragos Bogdan, Jonathan Cameron,
	Lars-Peter Clausen, Michael Hennerich, Krzysztof Kozlowski,
	Conor Dooley, Olivier Moysan
In-Reply-To: <20240328-iio-backend-axi-dac-v1-7-afc808b3fde3@analog.com>

On Thu, Mar 28, 2024 at 02:22:31PM +0100, Nuno Sa wrote:
> This adds the bindings documentation for the 14 bit
> RF Digital-to-Analog converter.

Reword the subject to say 'bindings' only once.

> 
> Signed-off-by: Nuno Sa <nuno.sa@analog.com>
> ---
>  .../devicetree/bindings/iio/dac/adi,ad9739a.yaml   | 88 ++++++++++++++++++++++
>  MAINTAINERS                                        |  8 ++
>  2 files changed, 96 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml
> new file mode 100644
> index 000000000000..24bcec763a9b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml
> @@ -0,0 +1,88 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iio/dac/adi,ad9739a.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices AD9739A RF DAC
> +
> +maintainers:
> +  - Dragos Bogdan <dragos.bogdan@analog.com>
> +  - Nuno Sa <nuno.sa@analog.com>
> +
> +description: |
> +  The AD9739A is a 14-bit, 2.5 GSPS high performance RF DACs that are capable
> +  of synthesizing wideband signals from dc up to 3 GHz.
> +
> +  https://www.analog.com/media/en/technical-documentation/data-sheets/ad9737a_9739a.pdf
> +
> +properties:
> +  compatible:
> +    enum:
> +      - adi,ad9739a
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  reset-gpios:
> +    maxItems: 1
> +
> +  vdd_3_3-supply:

vdd-3-3-supply or vdd-3p3-supply

> +    description: 3.3V Digital input supply.
> +
> +  vdd-supply:
> +    description: 1.8V Digital input supply.
> +
> +  vdda-supply:
> +    description: 3.3V Analog input supply.
> +
> +  vddc-supply:
> +    description: 1.8V Clock input supply.
> +
> +  io-backends:
> +    maxItems: 1
> +
> +  adi,full-scale-microamp:
> +    description: This property represents the DAC full scale current.
> +    minimum: 8700
> +    maximum: 31700
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - io-backends
> +  - vdd_3_3-supply
> +  - vdd-supply
> +  - vdda-supply
> +  - vddc-supply
> +
> +allOf:
> +  - $ref: /schemas/spi/spi-peripheral-props.yaml#
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    spi {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        dac@0 {
> +            compatible = "adi,ad9739a";
> +            reg = <0>;
> +
> +            clocks = <&dac_clk>;
> +
> +            io-backends = <&iio_backend>;
> +
> +            vdd_3_3-supply = <&vdd_3_3>;
> +            vdd-supply = <&vdd>;
> +            vdda-supply = <&vdd_3_3>;
> +            vddc-supply = <&vdd>;
> +        };
> +    };
> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 2137eb452376..76e872e320d7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1234,6 +1234,14 @@ W:	https://ez.analog.com/linux-software-drivers
>  F:	Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml
>  F:	drivers/iio/adc/ad7780.c
>  
> +ANALOG DEVICES INC AD9739a DRIVER
> +M:	Nuno Sa <nuno.sa@analog.com>
> +M:	Dragos Bogdan <dragos.bogdan@analog.com>
> +L:	linux-iio@vger.kernel.org
> +S:	Supported
> +W:	https://ez.analog.com/linux-software-drivers
> +F:	Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml
> +
>  ANALOG DEVICES INC ADA4250 DRIVER
>  M:	Antoniu Miclaus <antoniu.miclaus@analog.com>
>  L:	linux-iio@vger.kernel.org
> 
> -- 
> 2.44.0
> 

^ permalink raw reply

* Re: [PATCH 06/10] dt-bindings: iio: dac: add bindings doc for AXI DAC driver
From: Rob Herring @ 2024-04-01 13:59 UTC (permalink / raw)
  To: Nuno Sa
  Cc: linux-iio, devicetree, Dragos Bogdan, Jonathan Cameron,
	Lars-Peter Clausen, Michael Hennerich, Krzysztof Kozlowski,
	Conor Dooley, Olivier Moysan
In-Reply-To: <20240328-iio-backend-axi-dac-v1-6-afc808b3fde3@analog.com>

On Thu, Mar 28, 2024 at 02:22:30PM +0100, Nuno Sa wrote:
> This adds the bindings documentation for the AXI DAC driver.

Bindings are for h/w blocks, not 'drivers'.

Reword the subject to only say 'bindings' once.


> Signed-off-by: Nuno Sa <nuno.sa@analog.com>
> ---
>  .../devicetree/bindings/iio/dac/adi,axi-dac.yaml   | 62 ++++++++++++++++++++++
>  MAINTAINERS                                        |  7 +++
>  2 files changed, 69 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml
> new file mode 100644
> index 000000000000..1018fd274f04
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml
> @@ -0,0 +1,62 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iio/dac/adi,axi-dac.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices AXI DAC IP core
> +
> +maintainers:
> +  - Nuno Sa <nuno.sa@analog.com>
> +
> +description: |
> +  Analog Devices Generic AXI DAC IP core for interfacing a DAC device
> +  with a high speed serial (JESD204B/C) or source synchronous parallel
> +  interface (LVDS/CMOS).
> +  Usually, some other interface type (i.e SPI) is used as a control
> +  interface for the actual DAC, while this IP core will interface
> +  to the data-lines of the DAC and handle the streaming of data into
> +  memory via DMA.
> +
> +  https://wiki.analog.com/resources/fpga/docs/axi_dac_ip
> +
> +properties:
> +  compatible:
> +    enum:
> +      - adi,axi-dac-9.1.b
> +
> +  reg:
> +    maxItems: 1
> +
> +  dmas:
> +    maxItems: 1
> +
> +  dma-names:
> +    items:
> +      - const: tx

You don't need *-names if there is only 1 entry.

> +
> +  clocks:
> +    maxItems: 1
> +
> +  '#io-backend-cells':
> +    const: 0
> +
> +required:
> +  - compatible
> +  - dmas
> +  - reg
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    dac@44a00000 {
> +        compatible = "adi,axi-dac-9.1.b";
> +        reg = <0x44a00000 0x10000>;
> +        dmas = <&tx_dma 0>;
> +        dma-names = "tx";
> +        #io-backend-cells = <0>;
> +        clocks = <&axi_clk>;
> +    };
> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a7287cf44869..2137eb452376 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1399,6 +1399,13 @@ F:	sound/soc/codecs/adav*
>  F:	sound/soc/codecs/sigmadsp.*
>  F:	sound/soc/codecs/ssm*
>  
> +ANALOG DEVICES INC AXI DAC DRIVER
> +M:	Nuno Sa <nuno.sa@analog.com>
> +L:	linux-iio@vger.kernel.org
> +S:	Supported
> +W:	https://ez.analog.com/linux-software-drivers
> +F:	Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml
> +
>  ANALOG DEVICES INC DMA DRIVERS
>  M:	Lars-Peter Clausen <lars@metafoo.de>
>  S:	Supported
> 
> -- 
> 2.44.0
> 

^ permalink raw reply

* Re: [PATCH v6 3/4] dt-bindings: watchdog: aspeed-wdt: Add aspeed,scu
From: Rob Herring @ 2024-04-01 13:56 UTC (permalink / raw)
  To: Peter Yin
  Cc: patrick, Wim Van Sebroeck, Guenter Roeck, Krzysztof Kozlowski,
	Conor Dooley, Joel Stanley, Andrew Jeffery, linux-watchdog,
	devicetree, linux-arm-kernel, linux-aspeed, linux-kernel
In-Reply-To: <20240328022231.3649741-4-peteryin.openbmc@gmail.com>

On Thu, Mar 28, 2024 at 10:22:30AM +0800, Peter Yin wrote:
> To use the SCU register to obtain reset flags for supporting
> bootstatus.
> 
> Signed-off-by: Peter Yin <peteryin.openbmc@gmail.com>
> ---
>  Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
> index 3208adb3e52e..80a1f58b5a2e 100644
> --- a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
> +++ b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
> @@ -8,6 +8,8 @@ Required properties:
>  
>   - reg: physical base address of the controller and length of memory mapped
>     region
> + - aspeed,scu: a reference to the System Control Unit node of the Aspeed
> +   SOC.

You cannot add new required properties as that is an ABI break.

If there's only 1 SCU instance, you can just fetch its node by 
compatible with no DT change.

What's the plan for converting this binding to schema? This is the 2nd 
new property in 6 months.

Rob

^ permalink raw reply

* Re: [PATCH v7 09/15] media: bcm2835-unicam: Add support for CCP2/CSI2 camera interface
From: Laurent Pinchart @ 2024-04-01 13:52 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: linux-media, Dave Stevenson, David Plowman, Jean-Michel Hautbois,
	Hans Verkuil, Naushir Patuck, Sakari Ailus, kernel-list,
	linux-rpi-kernel, Florian Fainelli, Ray Jui, Scott Branden,
	bcm-kernel-feedback-list, Conor Dooley, Krzysztof Kozlowski,
	Rob Herring, devicetree
In-Reply-To: <b4506224-b75a-49d8-8651-a48f39149d52@ideasonboard.com>

On Wed, Mar 27, 2024 at 01:21:09PM +0200, Tomi Valkeinen wrote:
> On 25/03/2024 00:08, Laurent Pinchart wrote:
> > From: Dave Stevenson <dave.stevenson@raspberrypi.com>
> > 
> > Add a driver for the Unicam camera receiver block on BCM283x processors.
> > It is represented as two video device nodes: unicam-image and
> > unicam-embedded which are connected to an internal subdev (named
> > unicam-subdev) in order to manage streams routing.
> 
> Shouldn't this driver call get_frame_desc somewhere to get the VC and DT 
> for the streams?

Generally speaking, yes. In practice, configuring the DT from the frame
descriptor is probably not very useful, as CSI-2 sources that transmit
image data using a DT that doesn't correspond to the media bus code are
not very common and I don't expect this to be needed for unicam.
Configuring the VC, on the other hand, seems to me like a better use
case. I will add get_frame_desc support for the next version.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH v3 6/6] riscv: dts: starfive: add Milkv Mars board device tree
From: Heinrich Schuchardt @ 2024-04-01 13:28 UTC (permalink / raw)
  To: Jisheng Zhang
  Cc: Rob Herring, Krzysztof Kozlowski, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Emil Renner Berthing, linux-riscv, devicetree,
	linux-kernel, Conor Dooley, Aurelien Jarno
In-Reply-To: <ZgYn9t4akccWuHyf@xhacker>

On 3/29/24 03:31, Jisheng Zhang wrote:
> On Thu, Mar 28, 2024 at 10:28:28PM +0100, Heinrich Schuchardt wrote:
>> On 2/6/24 20:13, Conor Dooley wrote:
>>> On Wed, Jan 31, 2024 at 09:26:00PM +0800, Jisheng Zhang wrote:
>>>> The Milkv Mars is a development board based on the Starfive JH7110 SoC.
>>>> The board features:
>>>>
>>>> - JH7110 SoC
>>>> - 1/2/4/8 GiB LPDDR4 DRAM
>>>> - AXP15060 PMIC
>>>> - 40 pin GPIO header
>>>> - 3x USB 3.0 host port
>>>> - 1x USB 2.0 host port
>>>> - 1x M.2 E-Key
>>>> - 1x eMMC slot
>>>> - 1x MicroSD slot
>>>> - 1x QSPI Flash
>>>> - 1x 1Gbps Ethernet port
>>>> - 1x HDMI port
>>>> - 1x 2-lane DSI and 1x 4-lane DSI
>>>> - 1x 2-lane CSI
>>>>
>>>> Add the devicetree file describing the currently supported features,
>>>> namely PMIC, UART, I2C, GPIO, SD card, QSPI Flash, eMMC and Ethernet.
>>>>
>>>> Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
>>>
>>> Got a dtbs_check issue in the patchwork CI:
>>>
>>>     +arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dtb: gmac1-rgmii-rxin-clock: 'clock-frequency' is a required property
>>>     +	from schema $id: http://devicetree.org/schemas/clock/fixed-clock.yaml#
>>>     +arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dtb: gmac1-rmii-refin-clock: 'clock-frequency' is a required property
>>>     +	from schema $id: http://devicetree.org/schemas/clock/fixed-clock.yaml#
>>>
>>> Can you fix that please? Also, I applied some patches the other day that
>>> seem to conflict quite a bit with the common board dts patch. Would you
>>> please do a rebase on top of that please?
>>>
>>> Cheers,
>>> Conor.
>>>
>>>> ---
>>>>    arch/riscv/boot/dts/starfive/Makefile         |  1 +
>>>>    .../boot/dts/starfive/jh7110-milkv-mars.dts   | 35 +++++++++++++++++++
>>>>    2 files changed, 36 insertions(+)
>>>>    create mode 100644 arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
>>>>
>>>> diff --git a/arch/riscv/boot/dts/starfive/Makefile b/arch/riscv/boot/dts/starfive/Makefile
>>>> index 0141504c0f5c..2fa0cd7f31c3 100644
>>>> --- a/arch/riscv/boot/dts/starfive/Makefile
>>>> +++ b/arch/riscv/boot/dts/starfive/Makefile
>>>> @@ -8,5 +8,6 @@ DTC_FLAGS_jh7110-starfive-visionfive-2-v1.3b := -@
>>>>    dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
>>>>    dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
>>>> +dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-milkv-mars.dtb
>>>>    dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
>>>>    dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
>>>> diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
>>>> new file mode 100644
>>>> index 000000000000..de600e799e7d
>>>> --- /dev/null
>>>> +++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
>>>> @@ -0,0 +1,35 @@
>>>> +// SPDX-License-Identifier: GPL-2.0 OR MIT
>>>> +/*
>>>> + * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
>>>> + */
>>>> +
>>>> +/dts-v1/;
>>>> +#include "jh7110-visionfive2-mars-common.dtsi"
>>>> +
>>>> +/ {
>>>> +	model = "Milk-V Mars";
>>>> +	compatible = "milkv,mars", "starfive,jh7110";
>>>> +};
>>>> +
>>>> +&gmac0 {
>>>> +	starfive,tx-use-rgmii-clk;
>>>> +	assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>;
>>>> +	assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>;
>>>> +};
>>>> +
>>>> +
>>>> +&phy0 {
>>>> +	motorcomm,tx-clk-adj-enabled;
>>>> +	motorcomm,tx-clk-10-inverted;
>>>> +	motorcomm,tx-clk-100-inverted;
>>>> +	motorcomm,tx-clk-1000-inverted;
>>>> +	motorcomm,rx-clk-drv-microamp = <3970>;
>>>> +	motorcomm,rx-data-drv-microamp = <2910>;
>>>> +	rx-internal-delay-ps = <1500>;
>>>> +	tx-internal-delay-ps = <1500>;
>>>> +};
>>>> +
>>>> +&mmc1 {
>>>> +	disable-wp;
>>
>> Due to which difference is 'disable-wp' necessary for the Mars board and not
>> necessary for the VisionFive 2 board?
> 
> Mars doesn't have wp pin, but dunno vf2 case since I don't have a VF2
> board ;)

If the Milk-V Mars does not have a WP GPIO, we should be able to drop 
this property. The VisionFive 2 does not need it either.

>>
>>>> +	cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>;
>>
>> On my VisionFive 2 1.2B, and 1.3A boards GPIO 41 reflects if an SD-card is
>> inserted (as shown in U-Boot by gpio status -a). So shouldn't this value be
>> moved to the common include "jh7110-visionfive2-mars-common.dtsi" and
>> broken-cd removed from the VisionFive2 board?
> 
> I tested the CD pin and can confirm it works on Mars, but I dunno whether
> this works on VF2 since I have no VF2 board.
> Could you please check whether it works or not on VF2?

As mentioned in my prior mail the card detect GPIO is working on the 
VisionFive 2. StarFive acknowledged my U-Boot patch:

https://lore.kernel.org/u-boot/SHXPR01MB086314C47C281B3DDDF7BAE9E63AA@SHXPR01MB0863.CHNPR01.prod.partner.outlook.cn/

Best regards

Heinrich

> 
>>
>> https://doc-en.rvspace.org/VisionFive2/PDF/SCH_RV002_V1.2A_20221216.pdf
>> has a line
>>
>>      GPIO41 | SD_SDIO0_CD_GPIO41 | Micro SD:J10
>>
>> Best regards
>>
>> Heinrich
>>
>>>> +};
>>>> -- 
>>>> 2.43.0
>>


^ permalink raw reply

* Re: [PATCH v7 2/2] dmaengine: Loongson1: Add Loongson-1 APB DMA driver
From: Huacai Chen @ 2024-04-01 13:24 UTC (permalink / raw)
  To: Keguang Zhang
  Cc: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-mips, dmaengine, devicetree, linux-kernel
In-Reply-To: <CAJhJPsUW14vMAAhGTobCkSnYytwtUbdsZ5V9p33fzdnr3=L2Ag@mail.gmail.com>

On Mon, Apr 1, 2024 at 7:10 PM Keguang Zhang <keguang.zhang@gmail.com> wrote:
>
> On Mon, Apr 1, 2024 at 5:06 PM Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > On Mon, Apr 1, 2024 at 10:45 AM Keguang Zhang <keguang.zhang@gmail.com> wrote:
> > >
> > > Hi Huacai,
> > >
> > > On Sat, Mar 30, 2024 at 9:59 PM Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > Hi, Keguang,
> > > >
> > > > On Fri, Mar 29, 2024 at 7:28 PM Keguang Zhang via B4 Relay
> > > > <devnull+keguang.zhang.gmail.com@kernel.org> wrote:
> > > > >
> > > > > From: Keguang Zhang <keguang.zhang@gmail.com>
> > > > >
> > > > > This patch adds APB DMA driver for Loongson-1 SoCs.
> > > > >
> > > > > Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com>
> > > > > ---
> > > > > Changes in v7:
> > > > > - Change the comptible to 'loongson,ls1*-apbdma'
> > > > > - Update Kconfig and Makefile accordingly
> > > > > - Rename the file to loongson1-apb-dma.c to keep the consistency
> > > > >
> > > > > Changes in v6:
> > > > > - Implement .device_prep_dma_cyclic for Loongson1 audio driver,
> > > > > - as well as .device_pause and .device_resume.
> > > > > - Set the limitation LS1X_DMA_MAX_DESC and put all descriptors
> > > > > - into one page to save memory
> > > > > - Move dma_pool_zalloc() into ls1x_dma_alloc_desc()
> > > > > - Drop dma_slave_config structure
> > > > > - Use .remove_new instead of .remove
> > > > > - Use KBUILD_MODNAME for the driver name
> > > > > - Improve the debug information
> > > > >
> > > > > Changes in v5:
> > > > > - Add DT support
> > > > > - Use DT data instead of platform data
> > > > > - Use chan_id of struct dma_chan instead of own id
> > > > > - Use of_dma_xlate_by_chan_id() instead of ls1x_dma_filter()
> > > > > - Update the author information to my official name
> > > > >
> > > > > Changes in v4:
> > > > > - Use dma_slave_map to find the proper channel.
> > > > > - Explicitly call devm_request_irq() and tasklet_kill().
> > > > > - Fix namespace issue.
> > > > > - Some minor fixes and cleanups.
> > > > >
> > > > > Changes in v3:
> > > > > - Rename ls1x_dma_filter_fn to ls1x_dma_filter.
> > > > >
> > > > > Changes in v2:
> > > > > - Change the config from 'DMA_LOONGSON1' to 'LOONGSON1_DMA',
> > > > > - and rearrange it in alphabetical order in Kconfig and Makefile.
> > > > > - Fix comment style.
> > > > > ---
> > > > >  drivers/dma/Kconfig             |   9 +
> > > > >  drivers/dma/Makefile            |   1 +
> > > > >  drivers/dma/loongson1-apb-dma.c | 665 ++++++++++++++++++++++++++++++++++++++++
> > > > >  3 files changed, 675 insertions(+)
> > > > >
> > > > > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> > > > > index 002a5ec80620..f7b06c4cdf3f 100644
> > > > > --- a/drivers/dma/Kconfig
> > > > > +++ b/drivers/dma/Kconfig
> > > > > @@ -369,6 +369,15 @@ config K3_DMA
> > > > >           Support the DMA engine for Hisilicon K3 platform
> > > > >           devices.
> > > > >
> > > > > +config LOONGSON1_APB_DMA
> > > > > +       tristate "Loongson1 APB DMA support"
> > > > > +       depends on MACH_LOONGSON32 || COMPILE_TEST
> > > > > +       select DMA_ENGINE
> > > > > +       select DMA_VIRTUAL_CHANNELS
> > > > > +       help
> > > > > +         This selects support for the APB DMA controller in Loongson1 SoCs,
> > > > > +         which is required by Loongson1 NAND and audio support.
> > > > Why not rename to LS1X_APB_DMA and put it just before LS2X_APB_DMA
> > > > (and also the driver file name)?
> > > >
> > > So far all Kconfig entries of Loongson-1 drivers are named with the
> > > keyword "LOONGSON1".
> > > The same is true for these file names.
> > > Therefore, I need to keep the consistency.
> > But I see LS1X_IRQ in drivers/irqchip/Kconfig
> >
> Indeed, that's an exception, which was submitted by Jiaxun several years ago.
> Actually, most drivers of Loongson family use the keyword "LOONGSON"
> for Kconfig and "loongson" for filename.
> Thus I take this keywork as the naming convention.
But I think keeping consistency in a same subsystem is better than
keeping consistency in a same SoC (but cross subsystems).

Huacai

>
> > Huacai
> >
> > >
> > >
> > > > Huacai
> > > >
> > > > > +
> > > > >  config LPC18XX_DMAMUX
> > > > >         bool "NXP LPC18xx/43xx DMA MUX for PL080"
> > > > >         depends on ARCH_LPC18XX || COMPILE_TEST
> > > > > diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> > > > > index dfd40d14e408..b26f6677978a 100644
> > > > > --- a/drivers/dma/Makefile
> > > > > +++ b/drivers/dma/Makefile
> > > > > @@ -47,6 +47,7 @@ obj-$(CONFIG_INTEL_IDMA64) += idma64.o
> > > > >  obj-$(CONFIG_INTEL_IOATDMA) += ioat/
> > > > >  obj-y += idxd/
> > > > >  obj-$(CONFIG_K3_DMA) += k3dma.o
> > > > > +obj-$(CONFIG_LOONGSON1_APB_DMA) += loongson1-apb-dma.o
> > > > >  obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
> > > > >  obj-$(CONFIG_LS2X_APB_DMA) += ls2x-apb-dma.o
> > > > >  obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
> > > > > diff --git a/drivers/dma/loongson1-apb-dma.c b/drivers/dma/loongson1-apb-dma.c
> > > > > new file mode 100644
> > > > > index 000000000000..d474a2601e6e
> > > > > --- /dev/null
> > > > > +++ b/drivers/dma/loongson1-apb-dma.c
> > > > > @@ -0,0 +1,665 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0-or-later
> > > > > +/*
> > > > > + * Driver for Loongson-1 APB DMA Controller
> > > > > + *
> > > > > + * Copyright (C) 2015-2024 Keguang Zhang <keguang.zhang@gmail.com>
> > > > > + */
> > > > > +
> > > > > +#include <linux/dmapool.h>
> > > > > +#include <linux/dma-mapping.h>
> > > > > +#include <linux/init.h>
> > > > > +#include <linux/interrupt.h>
> > > > > +#include <linux/iopoll.h>
> > > > > +#include <linux/module.h>
> > > > > +#include <linux/of.h>
> > > > > +#include <linux/of_dma.h>
> > > > > +#include <linux/platform_device.h>
> > > > > +#include <linux/slab.h>
> > > > > +
> > > > > +#include "dmaengine.h"
> > > > > +#include "virt-dma.h"
> > > > > +
> > > > > +/* Loongson-1 DMA Control Register */
> > > > > +#define DMA_CTRL                       0x0
> > > > > +
> > > > > +/* DMA Control Register Bits */
> > > > > +#define DMA_STOP                       BIT(4)
> > > > > +#define DMA_START                      BIT(3)
> > > > > +#define DMA_ASK_VALID                  BIT(2)
> > > > > +
> > > > > +#define DMA_ADDR_MASK                  GENMASK(31, 6)
> > > > > +
> > > > > +/* DMA Next Field Bits */
> > > > > +#define DMA_NEXT_VALID                 BIT(0)
> > > > > +
> > > > > +/* DMA Command Field Bits */
> > > > > +#define DMA_RAM2DEV                    BIT(12)
> > > > > +#define DMA_INT                                BIT(1)
> > > > > +#define DMA_INT_MASK                   BIT(0)
> > > > > +
> > > > > +#define LS1X_DMA_MAX_CHANNELS          3
> > > > > +
> > > > > +/* Size of allocations for hardware descriptors */
> > > > > +#define LS1X_DMA_DESCS_SIZE            PAGE_SIZE
> > > > > +#define LS1X_DMA_MAX_DESC              \
> > > > > +       (LS1X_DMA_DESCS_SIZE / sizeof(struct ls1x_dma_hwdesc))
> > > > > +
> > > > > +struct ls1x_dma_hwdesc {
> > > > > +       u32 next;               /* next descriptor address */
> > > > > +       u32 saddr;              /* memory DMA address */
> > > > > +       u32 daddr;              /* device DMA address */
> > > > > +       u32 length;
> > > > > +       u32 stride;
> > > > > +       u32 cycles;
> > > > > +       u32 cmd;
> > > > > +       u32 stats;
> > > > > +};
> > > > > +
> > > > > +struct ls1x_dma_desc {
> > > > > +       struct virt_dma_desc vdesc;
> > > > > +       enum dma_transfer_direction dir;
> > > > > +       enum dma_transaction_type type;
> > > > > +       unsigned int bus_width;
> > > > > +
> > > > > +       unsigned int nr_descs;  /* number of descriptors */
> > > > > +
> > > > > +       struct ls1x_dma_hwdesc *hwdesc;
> > > > > +       dma_addr_t hwdesc_phys;
> > > > > +};
> > > > > +
> > > > > +struct ls1x_dma_chan {
> > > > > +       struct virt_dma_chan vchan;
> > > > > +       struct dma_pool *desc_pool;
> > > > > +       phys_addr_t src_addr;
> > > > > +       phys_addr_t dst_addr;
> > > > > +       enum dma_slave_buswidth src_addr_width;
> > > > > +       enum dma_slave_buswidth dst_addr_width;
> > > > > +
> > > > > +       void __iomem *reg_base;
> > > > > +       int irq;
> > > > > +
> > > > > +       struct ls1x_dma_desc *desc;
> > > > > +
> > > > > +       struct ls1x_dma_hwdesc *curr_hwdesc;
> > > > > +       dma_addr_t curr_hwdesc_phys;
> > > > > +};
> > > > > +
> > > > > +struct ls1x_dma {
> > > > > +       struct dma_device ddev;
> > > > > +       void __iomem *reg_base;
> > > > > +
> > > > > +       unsigned int nr_chans;
> > > > > +       struct ls1x_dma_chan chan[];
> > > > > +};
> > > > > +
> > > > > +#define to_ls1x_dma_chan(dchan)                \
> > > > > +       container_of(dchan, struct ls1x_dma_chan, vchan.chan)
> > > > > +
> > > > > +#define to_ls1x_dma_desc(vd)           \
> > > > > +       container_of(vd, struct ls1x_dma_desc, vdesc)
> > > > > +
> > > > > +/* macros for registers read/write */
> > > > > +#define chan_readl(chan, off)          \
> > > > > +       readl((chan)->reg_base + (off))
> > > > > +
> > > > > +#define chan_writel(chan, off, val)    \
> > > > > +       writel((val), (chan)->reg_base + (off))
> > > > > +
> > > > > +static inline struct device *chan2dev(struct dma_chan *chan)
> > > > > +{
> > > > > +       return &chan->dev->device;
> > > > > +}
> > > > > +
> > > > > +static inline int ls1x_dma_query(struct ls1x_dma_chan *chan,
> > > > > +                                dma_addr_t *hwdesc_phys)
> > > > > +{
> > > > > +       struct dma_chan *dchan = &chan->vchan.chan;
> > > > > +       int val, ret;
> > > > > +
> > > > > +       val = *hwdesc_phys & DMA_ADDR_MASK;
> > > > > +       val |= DMA_ASK_VALID;
> > > > > +       val |= dchan->chan_id;
> > > > > +       chan_writel(chan, DMA_CTRL, val);
> > > > > +       ret = readl_poll_timeout_atomic(chan->reg_base + DMA_CTRL, val,
> > > > > +                                       !(val & DMA_ASK_VALID), 0, 3000);
> > > > > +       if (ret)
> > > > > +               dev_err(chan2dev(dchan), "failed to query DMA\n");
> > > > > +
> > > > > +       return ret;
> > > > > +}
> > > > > +
> > > > > +static inline int ls1x_dma_start(struct ls1x_dma_chan *chan,
> > > > > +                                dma_addr_t *hwdesc_phys)
> > > > > +{
> > > > > +       struct dma_chan *dchan = &chan->vchan.chan;
> > > > > +       int val, ret;
> > > > > +
> > > > > +       dev_dbg(chan2dev(dchan), "cookie=%d, starting hwdesc=%x\n",
> > > > > +               dchan->cookie, *hwdesc_phys);
> > > > > +
> > > > > +       val = *hwdesc_phys & DMA_ADDR_MASK;
> > > > > +       val |= DMA_START;
> > > > > +       val |= dchan->chan_id;
> > > > > +       chan_writel(chan, DMA_CTRL, val);
> > > > > +       ret = readl_poll_timeout(chan->reg_base + DMA_CTRL, val,
> > > > > +                                !(val & DMA_START), 0, 3000);
> > > > > +       if (ret)
> > > > > +               dev_err(chan2dev(dchan), "failed to start DMA\n");
> > > > > +
> > > > > +       return ret;
> > > > > +}
> > > > > +
> > > > > +static inline void ls1x_dma_stop(struct ls1x_dma_chan *chan)
> > > > > +{
> > > > > +       chan_writel(chan, DMA_CTRL, chan_readl(chan, DMA_CTRL) | DMA_STOP);
> > > > > +}
> > > > > +
> > > > > +static void ls1x_dma_free_chan_resources(struct dma_chan *dchan)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +
> > > > > +       dma_free_coherent(chan2dev(dchan), sizeof(struct ls1x_dma_hwdesc),
> > > > > +                         chan->curr_hwdesc, chan->curr_hwdesc_phys);
> > > > > +       vchan_free_chan_resources(&chan->vchan);
> > > > > +       dma_pool_destroy(chan->desc_pool);
> > > > > +       chan->desc_pool = NULL;
> > > > > +}
> > > > > +
> > > > > +static int ls1x_dma_alloc_chan_resources(struct dma_chan *dchan)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +
> > > > > +       chan->desc_pool = dma_pool_create(dma_chan_name(dchan),
> > > > > +                                         chan2dev(dchan),
> > > > > +                                         sizeof(struct ls1x_dma_hwdesc),
> > > > > +                                         __alignof__(struct ls1x_dma_hwdesc),
> > > > > +                                         0);
> > > > > +       if (!chan->desc_pool)
> > > > > +               return -ENOMEM;
> > > > > +
> > > > > +       /* allocate memory for querying current HW descriptor */
> > > > > +       dma_set_coherent_mask(chan2dev(dchan), DMA_BIT_MASK(32));
> > > > > +       chan->curr_hwdesc = dma_alloc_coherent(chan2dev(dchan),
> > > > > +                                              sizeof(struct ls1x_dma_hwdesc),
> > > > > +                                              &chan->curr_hwdesc_phys,
> > > > > +                                              GFP_KERNEL);
> > > > > +       if (!chan->curr_hwdesc)
> > > > > +               return -ENOMEM;
> > > > > +
> > > > > +       return 0;
> > > > > +}
> > > > > +
> > > > > +static void ls1x_dma_free_desc(struct virt_dma_desc *vdesc)
> > > > > +{
> > > > > +       struct ls1x_dma_desc *desc = to_ls1x_dma_desc(vdesc);
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(vdesc->tx.chan);
> > > > > +
> > > > > +       dma_pool_free(chan->desc_pool, desc->hwdesc, desc->hwdesc_phys);
> > > > > +       chan->desc = NULL;
> > > > > +       kfree(desc);
> > > > > +}
> > > > > +
> > > > > +static struct ls1x_dma_desc *
> > > > > +ls1x_dma_alloc_desc(struct dma_chan *dchan, int sg_len,
> > > > > +                   enum dma_transfer_direction direction,
> > > > > +                   enum dma_transaction_type type)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +       struct ls1x_dma_desc *desc;
> > > > > +
> > > > > +       if (sg_len > LS1X_DMA_MAX_DESC) {
> > > > > +               dev_err(chan2dev(dchan), "sg_len %u exceeds limit %lu",
> > > > > +                       sg_len, LS1X_DMA_MAX_DESC);
> > > > > +               return NULL;
> > > > > +       }
> > > > > +
> > > > > +       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
> > > > > +       if (!desc)
> > > > > +               return NULL;
> > > > > +
> > > > > +       /* allocate HW descriptors */
> > > > > +       desc->hwdesc = dma_pool_zalloc(chan->desc_pool, GFP_NOWAIT,
> > > > > +                                      &desc->hwdesc_phys);
> > > > > +       if (!desc->hwdesc) {
> > > > > +               dev_err(chan2dev(dchan), "failed to alloc HW descriptors\n");
> > > > > +               ls1x_dma_free_desc(&desc->vdesc);
> > > > > +               return NULL;
> > > > > +       }
> > > > > +
> > > > > +       desc->dir = direction;
> > > > > +       desc->type = type;
> > > > > +       desc->nr_descs = sg_len;
> > > > > +
> > > > > +       return desc;
> > > > > +}
> > > > > +
> > > > > +static int ls1x_dma_setup_hwdescs(struct dma_chan *dchan,
> > > > > +                                 struct ls1x_dma_desc *desc,
> > > > > +                                 struct scatterlist *sgl, unsigned int sg_len)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +       dma_addr_t next_hwdesc_phys = desc->hwdesc_phys;
> > > > > +
> > > > > +       struct scatterlist *sg;
> > > > > +       unsigned int dev_addr, cmd, i;
> > > > > +
> > > > > +       switch (desc->dir) {
> > > > > +       case DMA_MEM_TO_DEV:
> > > > > +               dev_addr = chan->dst_addr;
> > > > > +               desc->bus_width = chan->dst_addr_width;
> > > > > +               cmd = DMA_RAM2DEV | DMA_INT;
> > > > > +               break;
> > > > > +       case DMA_DEV_TO_MEM:
> > > > > +               dev_addr = chan->src_addr;
> > > > > +               desc->bus_width = chan->src_addr_width;
> > > > > +               cmd = DMA_INT;
> > > > > +               break;
> > > > > +       default:
> > > > > +               dev_err(chan2dev(dchan), "unsupported DMA direction: %s\n",
> > > > > +                       dmaengine_get_direction_text(desc->dir));
> > > > > +               return -EINVAL;
> > > > > +       }
> > > > > +
> > > > > +       /* setup HW descriptors */
> > > > > +       for_each_sg(sgl, sg, sg_len, i) {
> > > > > +               dma_addr_t buf_addr = sg_dma_address(sg);
> > > > > +               size_t buf_len = sg_dma_len(sg);
> > > > > +               struct ls1x_dma_hwdesc *hwdesc = &desc->hwdesc[i];
> > > > > +
> > > > > +               if (!is_dma_copy_aligned(dchan->device, buf_addr, 0, buf_len)) {
> > > > > +                       dev_err(chan2dev(dchan), "buffer is not aligned!\n");
> > > > > +                       return -EINVAL;
> > > > > +               }
> > > > > +
> > > > > +               hwdesc->saddr = buf_addr;
> > > > > +               hwdesc->daddr = dev_addr;
> > > > > +               hwdesc->length = buf_len / desc->bus_width;
> > > > > +               hwdesc->stride = 0;
> > > > > +               hwdesc->cycles = 1;
> > > > > +               hwdesc->cmd = cmd;
> > > > > +
> > > > > +               if (i) {
> > > > > +                       next_hwdesc_phys += sizeof(*hwdesc);
> > > > > +                       desc->hwdesc[i - 1].next = next_hwdesc_phys
> > > > > +                           | DMA_NEXT_VALID;
> > > > > +               }
> > > > > +       }
> > > > > +
> > > > > +       if (desc->type == DMA_CYCLIC)
> > > > > +               desc->hwdesc[i - 1].next = desc->hwdesc_phys | DMA_NEXT_VALID;
> > > > > +
> > > > > +       for_each_sg(sgl, sg, sg_len, i) {
> > > > > +               struct ls1x_dma_hwdesc *hwdesc = &desc->hwdesc[i];
> > > > > +
> > > > > +               print_hex_dump_debug("HW DESC: ", DUMP_PREFIX_OFFSET, 16, 4,
> > > > > +                                    hwdesc, sizeof(*hwdesc), false);
> > > > > +       }
> > > > > +
> > > > > +       return 0;
> > > > > +}
> > > > > +
> > > > > +static struct dma_async_tx_descriptor *
> > > > > +ls1x_dma_prep_slave_sg(struct dma_chan *dchan,
> > > > > +                      struct scatterlist *sgl, unsigned int sg_len,
> > > > > +                      enum dma_transfer_direction direction,
> > > > > +                      unsigned long flags, void *context)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +       struct ls1x_dma_desc *desc;
> > > > > +
> > > > > +       dev_dbg(chan2dev(dchan), "sg_len=%u flags=0x%lx dir=%s\n",
> > > > > +               sg_len, flags, dmaengine_get_direction_text(direction));
> > > > > +
> > > > > +       desc = ls1x_dma_alloc_desc(dchan, sg_len, direction, DMA_SLAVE);
> > > > > +       if (!desc)
> > > > > +               return NULL;
> > > > > +
> > > > > +       if (ls1x_dma_setup_hwdescs(dchan, desc, sgl, sg_len)) {
> > > > > +               ls1x_dma_free_desc(&desc->vdesc);
> > > > > +               return NULL;
> > > > > +       }
> > > > > +
> > > > > +       return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
> > > > > +}
> > > > > +
> > > > > +static struct dma_async_tx_descriptor *
> > > > > +ls1x_dma_prep_dma_cyclic(struct dma_chan *dchan,
> > > > > +                        dma_addr_t buf_addr, size_t buf_len, size_t period_len,
> > > > > +                        enum dma_transfer_direction direction,
> > > > > +                        unsigned long flags)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +       struct ls1x_dma_desc *desc;
> > > > > +       struct scatterlist *sgl;
> > > > > +       unsigned int sg_len;
> > > > > +       unsigned int i;
> > > > > +
> > > > > +       dev_dbg(chan2dev(dchan),
> > > > > +               "buf_len=%d period_len=%zu flags=0x%lx dir=%s\n", buf_len,
> > > > > +               period_len, flags, dmaengine_get_direction_text(direction));
> > > > > +
> > > > > +       sg_len = buf_len / period_len;
> > > > > +       desc = ls1x_dma_alloc_desc(dchan, sg_len, direction, DMA_CYCLIC);
> > > > > +       if (!desc)
> > > > > +               return NULL;
> > > > > +
> > > > > +       /* allocate the scatterlist */
> > > > > +       sgl = kmalloc_array(sg_len, sizeof(*sgl), GFP_NOWAIT);
> > > > > +       if (!sgl)
> > > > > +               return NULL;
> > > > > +
> > > > > +       sg_init_table(sgl, sg_len);
> > > > > +       for (i = 0; i < sg_len; ++i) {
> > > > > +               sg_set_page(&sgl[i], pfn_to_page(PFN_DOWN(buf_addr)),
> > > > > +                           period_len, offset_in_page(buf_addr));
> > > > > +               sg_dma_address(&sgl[i]) = buf_addr;
> > > > > +               sg_dma_len(&sgl[i]) = period_len;
> > > > > +               buf_addr += period_len;
> > > > > +       }
> > > > > +
> > > > > +       if (ls1x_dma_setup_hwdescs(dchan, desc, sgl, sg_len)) {
> > > > > +               ls1x_dma_free_desc(&desc->vdesc);
> > > > > +               return NULL;
> > > > > +       }
> > > > > +
> > > > > +       kfree(sgl);
> > > > > +
> > > > > +       return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
> > > > > +}
> > > > > +
> > > > > +static int ls1x_dma_slave_config(struct dma_chan *dchan,
> > > > > +                                struct dma_slave_config *config)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +
> > > > > +       chan->src_addr = config->src_addr;
> > > > > +       chan->src_addr_width = config->src_addr_width;
> > > > > +       chan->dst_addr = config->dst_addr;
> > > > > +       chan->dst_addr_width = config->dst_addr_width;
> > > > > +
> > > > > +       return 0;
> > > > > +}
> > > > > +
> > > > > +static int ls1x_dma_pause(struct dma_chan *dchan)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +       unsigned long flags;
> > > > > +       int ret;
> > > > > +
> > > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > > +       ret = ls1x_dma_query(chan, &chan->curr_hwdesc_phys);
> > > > > +       if (!ret)
> > > > > +               ls1x_dma_stop(chan);
> > > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > > +
> > > > > +       return ret;
> > > > > +}
> > > > > +
> > > > > +static int ls1x_dma_resume(struct dma_chan *dchan)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +       unsigned long flags;
> > > > > +       int ret;
> > > > > +
> > > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > > +       ret = ls1x_dma_start(chan, &chan->curr_hwdesc_phys);
> > > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > > +
> > > > > +       return ret;
> > > > > +}
> > > > > +
> > > > > +static int ls1x_dma_terminate_all(struct dma_chan *dchan)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +       unsigned long flags;
> > > > > +       LIST_HEAD(head);
> > > > > +
> > > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > > +       ls1x_dma_stop(chan);
> > > > > +       vchan_get_all_descriptors(&chan->vchan, &head);
> > > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > > +
> > > > > +       vchan_dma_desc_free_list(&chan->vchan, &head);
> > > > > +
> > > > > +       return 0;
> > > > > +}
> > > > > +
> > > > > +static enum dma_status ls1x_dma_tx_status(struct dma_chan *dchan,
> > > > > +                                         dma_cookie_t cookie,
> > > > > +                                         struct dma_tx_state *state)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +       struct virt_dma_desc *vdesc;
> > > > > +       enum dma_status status;
> > > > > +       size_t bytes = 0;
> > > > > +       unsigned long flags;
> > > > > +
> > > > > +       status = dma_cookie_status(dchan, cookie, state);
> > > > > +       if (status == DMA_COMPLETE)
> > > > > +               return status;
> > > > > +
> > > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > > +       vdesc = vchan_find_desc(&chan->vchan, cookie);
> > > > > +       if (chan->desc && cookie == chan->desc->vdesc.tx.cookie) {
> > > > > +               struct ls1x_dma_desc *desc = chan->desc;
> > > > > +               int i;
> > > > > +
> > > > > +               if (ls1x_dma_query(chan, &chan->curr_hwdesc_phys))
> > > > > +                       return status;
> > > > > +
> > > > > +               /* locate the current HW descriptor */
> > > > > +               for (i = 0; i < desc->nr_descs; i++)
> > > > > +                       if (desc->hwdesc[i].next == chan->curr_hwdesc->next)
> > > > > +                               break;
> > > > > +
> > > > > +               /* count the residues */
> > > > > +               for (; i < desc->nr_descs; i++)
> > > > > +                       bytes += desc->hwdesc[i].length * desc->bus_width;
> > > > > +
> > > > > +               dma_set_residue(state, bytes);
> > > > > +       }
> > > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > > +
> > > > > +       return status;
> > > > > +}
> > > > > +
> > > > > +static void ls1x_dma_issue_pending(struct dma_chan *dchan)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > > +       struct virt_dma_desc *vdesc;
> > > > > +       unsigned long flags;
> > > > > +
> > > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > > +       if (vchan_issue_pending(&chan->vchan) && !chan->desc) {
> > > > > +               vdesc = vchan_next_desc(&chan->vchan);
> > > > > +               if (!vdesc) {
> > > > > +                       chan->desc = NULL;
> > > > > +                       return;
> > > > > +               }
> > > > > +               chan->desc = to_ls1x_dma_desc(vdesc);
> > > > > +               ls1x_dma_start(chan, &chan->desc->hwdesc_phys);
> > > > > +       }
> > > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > > +}
> > > > > +
> > > > > +static irqreturn_t ls1x_dma_irq_handler(int irq, void *data)
> > > > > +{
> > > > > +       struct ls1x_dma_chan *chan = data;
> > > > > +       struct ls1x_dma_desc *desc = chan->desc;
> > > > > +       struct dma_chan *dchan = &chan->vchan.chan;
> > > > > +
> > > > > +       if (!desc) {
> > > > > +               dev_warn(chan2dev(dchan),
> > > > > +                        "IRQ %d with no active descriptor on channel %d\n",
> > > > > +                        irq, dchan->chan_id);
> > > > > +               return IRQ_NONE;
> > > > > +       }
> > > > > +
> > > > > +       dev_dbg(chan2dev(dchan), "DMA IRQ %d on channel %d\n", irq,
> > > > > +               dchan->chan_id);
> > > > > +
> > > > > +       spin_lock(&chan->vchan.lock);
> > > > > +
> > > > > +       if (desc->type == DMA_CYCLIC) {
> > > > > +               vchan_cyclic_callback(&desc->vdesc);
> > > > > +       } else {
> > > > > +               list_del(&desc->vdesc.node);
> > > > > +               vchan_cookie_complete(&desc->vdesc);
> > > > > +               chan->desc = NULL;
> > > > > +       }
> > > > > +
> > > > > +       spin_unlock(&chan->vchan.lock);
> > > > > +       return IRQ_HANDLED;
> > > > > +}
> > > > > +
> > > > > +static int ls1x_dma_chan_probe(struct platform_device *pdev,
> > > > > +                              struct ls1x_dma *dma, int chan_id)
> > > > > +{
> > > > > +       struct device *dev = &pdev->dev;
> > > > > +       struct ls1x_dma_chan *chan = &dma->chan[chan_id];
> > > > > +       char pdev_irqname[4];
> > > > > +       char *irqname;
> > > > > +       int ret;
> > > > > +
> > > > > +       sprintf(pdev_irqname, "ch%u", chan_id);
> > > > > +       chan->irq = platform_get_irq_byname(pdev, pdev_irqname);
> > > > > +       if (chan->irq < 0)
> > > > > +               return -ENODEV;
> > > > > +
> > > > > +       irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:%s",
> > > > > +                                dev_name(dev), pdev_irqname);
> > > > > +       if (!irqname)
> > > > > +               return -ENOMEM;
> > > > > +
> > > > > +       ret = devm_request_irq(dev, chan->irq, ls1x_dma_irq_handler,
> > > > > +                              IRQF_SHARED, irqname, chan);
> > > > > +       if (ret)
> > > > > +               return dev_err_probe(dev, ret,
> > > > > +                                    "failed to request IRQ %u!\n", chan->irq);
> > > > > +
> > > > > +       chan->reg_base = dma->reg_base;
> > > > > +       chan->vchan.desc_free = ls1x_dma_free_desc;
> > > > > +       vchan_init(&chan->vchan, &dma->ddev);
> > > > > +       dev_info(dev, "%s (irq %d) initialized\n", pdev_irqname, chan->irq);
> > > > > +
> > > > > +       return 0;
> > > > > +}
> > > > > +
> > > > > +static void ls1x_dma_chan_remove(struct ls1x_dma *dma, int chan_id)
> > > > > +{
> > > > > +       struct device *dev = dma->ddev.dev;
> > > > > +       struct ls1x_dma_chan *chan = &dma->chan[chan_id];
> > > > > +
> > > > > +       devm_free_irq(dev, chan->irq, chan);
> > > > > +       list_del(&chan->vchan.chan.device_node);
> > > > > +       tasklet_kill(&chan->vchan.task);
> > > > > +}
> > > > > +
> > > > > +static int ls1x_dma_probe(struct platform_device *pdev)
> > > > > +{
> > > > > +       struct device *dev = &pdev->dev;
> > > > > +       struct dma_device *ddev;
> > > > > +       struct ls1x_dma *dma;
> > > > > +       int nr_chans, ret, i;
> > > > > +
> > > > > +       nr_chans = platform_irq_count(pdev);
> > > > > +       if (nr_chans <= 0)
> > > > > +               return nr_chans;
> > > > > +       if (nr_chans > LS1X_DMA_MAX_CHANNELS)
> > > > > +               return dev_err_probe(dev, -EINVAL,
> > > > > +                                    "nr_chans=%d exceeds the maximum\n",
> > > > > +                                    nr_chans);
> > > > > +
> > > > > +       dma = devm_kzalloc(dev, struct_size(dma, chan, nr_chans), GFP_KERNEL);
> > > > > +       if (!dma)
> > > > > +               return -ENOMEM;
> > > > > +
> > > > > +       /* initialize DMA device */
> > > > > +       dma->reg_base = devm_platform_ioremap_resource(pdev, 0);
> > > > > +       if (IS_ERR(dma->reg_base))
> > > > > +               return PTR_ERR(dma->reg_base);
> > > > > +
> > > > > +       ddev = &dma->ddev;
> > > > > +       ddev->dev = dev;
> > > > > +       ddev->copy_align = DMAENGINE_ALIGN_4_BYTES;
> > > > > +       ddev->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> > > > > +           BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> > > > > +       ddev->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> > > > > +           BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> > > > > +       ddev->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
> > > > > +       ddev->max_sg_burst = LS1X_DMA_MAX_DESC;
> > > > > +       ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
> > > > > +       ddev->device_alloc_chan_resources = ls1x_dma_alloc_chan_resources;
> > > > > +       ddev->device_free_chan_resources = ls1x_dma_free_chan_resources;
> > > > > +       ddev->device_prep_slave_sg = ls1x_dma_prep_slave_sg;
> > > > > +       ddev->device_prep_dma_cyclic = ls1x_dma_prep_dma_cyclic;
> > > > > +       ddev->device_config = ls1x_dma_slave_config;
> > > > > +       ddev->device_pause = ls1x_dma_pause;
> > > > > +       ddev->device_resume = ls1x_dma_resume;
> > > > > +       ddev->device_terminate_all = ls1x_dma_terminate_all;
> > > > > +       ddev->device_tx_status = ls1x_dma_tx_status;
> > > > > +       ddev->device_issue_pending = ls1x_dma_issue_pending;
> > > > > +
> > > > > +       dma_cap_set(DMA_SLAVE, ddev->cap_mask);
> > > > > +       INIT_LIST_HEAD(&ddev->channels);
> > > > > +
> > > > > +       /* initialize DMA channels */
> > > > > +       for (i = 0; i < nr_chans; i++) {
> > > > > +               ret = ls1x_dma_chan_probe(pdev, dma, i);
> > > > > +               if (ret)
> > > > > +                       return ret;
> > > > > +       }
> > > > > +       dma->nr_chans = nr_chans;
> > > > > +
> > > > > +       ret = dmaenginem_async_device_register(ddev);
> > > > > +       if (ret) {
> > > > > +               dev_err(dev, "failed to register DMA device! %d\n", ret);
> > > > > +               return ret;
> > > > > +       }
> > > > > +
> > > > > +       ret =
> > > > > +           of_dma_controller_register(dev->of_node, of_dma_xlate_by_chan_id,
> > > > > +                                      ddev);
> > > > > +       if (ret) {
> > > > > +               dev_err(dev, "failed to register DMA controller! %d\n", ret);
> > > > > +               return ret;
> > > > > +       }
> > > > > +
> > > > > +       platform_set_drvdata(pdev, dma);
> > > > > +       dev_info(dev, "Loongson1 DMA driver registered\n");
> > > > > +
> > > > > +       return 0;
> > > > > +}
> > > > > +
> > > > > +static void ls1x_dma_remove(struct platform_device *pdev)
> > > > > +{
> > > > > +       struct ls1x_dma *dma = platform_get_drvdata(pdev);
> > > > > +       int i;
> > > > > +
> > > > > +       of_dma_controller_free(pdev->dev.of_node);
> > > > > +
> > > > > +       for (i = 0; i < dma->nr_chans; i++)
> > > > > +               ls1x_dma_chan_remove(dma, i);
> > > > > +}
> > > > > +
> > > > > +static const struct of_device_id ls1x_dma_match[] = {
> > > > > +       { .compatible = "loongson,ls1b-apbdma" },
> > > > > +       { .compatible = "loongson,ls1c-apbdma" },
> > > > > +       { /* sentinel */ }
> > > > > +};
> > > > > +MODULE_DEVICE_TABLE(of, ls1x_dma_match);
> > > > > +
> > > > > +static struct platform_driver ls1x_dma_driver = {
> > > > > +       .probe = ls1x_dma_probe,
> > > > > +       .remove_new = ls1x_dma_remove,
> > > > > +       .driver = {
> > > > > +               .name = KBUILD_MODNAME,
> > > > > +               .of_match_table = ls1x_dma_match,
> > > > > +       },
> > > > > +};
> > > > > +
> > > > > +module_platform_driver(ls1x_dma_driver);
> > > > > +
> > > > > +MODULE_AUTHOR("Keguang Zhang <keguang.zhang@gmail.com>");
> > > > > +MODULE_DESCRIPTION("Loongson-1 APB DMA Controller driver");
> > > > > +MODULE_LICENSE("GPL");
> > > > >
> > > > > --
> > > > > 2.40.1
> > > > >
> > > > >
> > >
> > >
> > >
> > > --
> > > Best regards,
> > >
> > > Keguang Zhang
> > >
>
>
>
> --
> Best regards,
>
> Keguang Zhang

^ permalink raw reply

* [PATCH v6 4/4] clk: imx: add i.MX95 BLK CTL clk driver
From: Peng Fan (OSS) @ 2024-04-01 13:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Abel Vesa
  Cc: linux-clk, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan
In-Reply-To: <20240401-imx95-blk-ctl-v6-0-84d4eca1e759@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

i.MX95 has BLK CTL modules in various MIXes, the BLK CTL modules
support clock features such as mux/gate/div. This patch
is to add the clock feature of BLK CTL modules

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/clk/imx/Kconfig             |   7 +
 drivers/clk/imx/Makefile            |   1 +
 drivers/clk/imx/clk-imx95-blk-ctl.c | 438 ++++++++++++++++++++++++++++++++++++
 3 files changed, 446 insertions(+)

diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index db3bca5f4ec9..6da0fba68225 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -114,6 +114,13 @@ config CLK_IMX93
 	help
 	    Build the driver for i.MX93 CCM Clock Driver
 
+config CLK_IMX95_BLK_CTL
+	tristate "IMX95 Clock Driver for BLK CTL"
+	depends on ARCH_MXC || COMPILE_TEST
+	select MXC_CLK
+	help
+	    Build the clock driver for i.MX95 BLK CTL
+
 config CLK_IMXRT1050
 	tristate "IMXRT1050 CCM Clock Driver"
 	depends on SOC_IMXRT || COMPILE_TEST
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index d4b8e10b1970..03f2b2a1ab63 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-imx8mp-audiomix.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 
 obj-$(CONFIG_CLK_IMX93) += clk-imx93.o
+obj-$(CONFIG_CLK_IMX95_BLK_CTL) += clk-imx95-blk-ctl.o
 
 obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o clk-imx-acm.o
 clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o \
diff --git a/drivers/clk/imx/clk-imx95-blk-ctl.c b/drivers/clk/imx/clk-imx95-blk-ctl.c
new file mode 100644
index 000000000000..74f595f9e5e3
--- /dev/null
+++ b/drivers/clk/imx/clk-imx95-blk-ctl.c
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2024 NXP
+ */
+
+#include <dt-bindings/clock/nxp,imx95-clock.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/pm_runtime.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+enum {
+	CLK_GATE,
+	CLK_DIVIDER,
+	CLK_MUX,
+};
+
+struct imx95_blk_ctl {
+	struct device *dev;
+	spinlock_t lock;
+	struct clk *clk_apb;
+
+	void __iomem *base;
+	/* clock gate register */
+	u32 clk_reg_restore;
+};
+
+struct imx95_blk_ctl_clk_dev_data {
+	const char *name;
+	const char * const *parent_names;
+	u32 num_parents;
+	u32 reg;
+	u32 bit_idx;
+	u32 bit_width;
+	u32 clk_type;
+	u32 flags;
+	u32 flags2;
+	u32 type;
+};
+
+struct imx95_blk_ctl_dev_data {
+	const struct imx95_blk_ctl_clk_dev_data *clk_dev_data;
+	u32 num_clks;
+	bool rpm_enabled;
+	u32 clk_reg_offset;
+};
+
+static const struct imx95_blk_ctl_clk_dev_data vpublk_clk_dev_data[] = {
+	[IMX95_CLK_VPUBLK_WAVE] = {
+		.name = "vpublk_wave_vpu",
+		.parent_names = (const char *[]){ "vpu", },
+		.num_parents = 1,
+		.reg = 8,
+		.bit_idx = 0,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	},
+	[IMX95_CLK_VPUBLK_JPEG_ENC] = {
+		.name = "vpublk_jpeg_enc",
+		.parent_names = (const char *[]){ "vpujpeg", },
+		.num_parents = 1,
+		.reg = 8,
+		.bit_idx = 1,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	},
+	[IMX95_CLK_VPUBLK_JPEG_DEC] = {
+		.name = "vpublk_jpeg_dec",
+		.parent_names = (const char *[]){ "vpujpeg", },
+		.num_parents = 1,
+		.reg = 8,
+		.bit_idx = 2,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	}
+};
+
+static const struct imx95_blk_ctl_dev_data vpublk_dev_data = {
+	.num_clks = ARRAY_SIZE(vpublk_clk_dev_data),
+	.clk_dev_data = vpublk_clk_dev_data,
+	.rpm_enabled = true,
+	.clk_reg_offset = 8,
+};
+
+static const struct imx95_blk_ctl_clk_dev_data camblk_clk_dev_data[] = {
+	[IMX95_CLK_CAMBLK_CSI2_FOR0] = {
+		.name = "camblk_csi2_for0",
+		.parent_names = (const char *[]){ "camisi", },
+		.num_parents = 1,
+		.reg = 0,
+		.bit_idx = 0,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	},
+	[IMX95_CLK_CAMBLK_CSI2_FOR1] = {
+		.name = "camblk_csi2_for1",
+		.parent_names = (const char *[]){ "camisi", },
+		.num_parents = 1,
+		.reg = 0,
+		.bit_idx = 1,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	},
+	[IMX95_CLK_CAMBLK_ISP_AXI] = {
+		.name = "camblk_isp_axi",
+		.parent_names = (const char *[]){ "camaxi", },
+		.num_parents = 1,
+		.reg = 0,
+		.bit_idx = 4,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	},
+	[IMX95_CLK_CAMBLK_ISP_PIXEL] = {
+		.name = "camblk_isp_pixel",
+		.parent_names = (const char *[]){ "camisi", },
+		.num_parents = 1,
+		.reg = 0,
+		.bit_idx = 5,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	},
+	[IMX95_CLK_CAMBLK_ISP] = {
+		.name = "camblk_isp",
+		.parent_names = (const char *[]){ "camisi", },
+		.num_parents = 1,
+		.reg = 0,
+		.bit_idx = 6,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	}
+};
+
+static const struct imx95_blk_ctl_dev_data camblk_dev_data = {
+	.num_clks = ARRAY_SIZE(camblk_clk_dev_data),
+	.clk_dev_data = camblk_clk_dev_data,
+	.clk_reg_offset = 0,
+};
+
+static const struct imx95_blk_ctl_clk_dev_data lvds_clk_dev_data[] = {
+	[IMX95_CLK_DISPMIX_LVDS_PHY_DIV] = {
+		.name = "ldb_phy_div",
+		.parent_names = (const char *[]){ "ldbpll", },
+		.num_parents = 1,
+		.reg = 0,
+		.bit_idx = 0,
+		.bit_width = 1,
+		.type = CLK_DIVIDER,
+		.flags2 = CLK_DIVIDER_POWER_OF_TWO,
+	},
+	[IMX95_CLK_DISPMIX_LVDS_CH0_GATE] = {
+		.name = "lvds_ch0_gate",
+		.parent_names = (const char *[]){ "ldb_phy_div", },
+		.num_parents = 1,
+		.reg = 0,
+		.bit_idx = 1,
+		.bit_width = 1,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	},
+	[IMX95_CLK_DISPMIX_LVDS_CH1_GATE] = {
+		.name = "lvds_ch1_gate",
+		.parent_names = (const char *[]){ "ldb_phy_div", },
+		.num_parents = 1,
+		.reg = 0,
+		.bit_idx = 2,
+		.bit_width = 1,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	},
+	[IMX95_CLK_DISPMIX_PIX_DI0_GATE] = {
+		.name = "lvds_di0_gate",
+		.parent_names = (const char *[]){ "ldb_pll_div7", },
+		.num_parents = 1,
+		.reg = 0,
+		.bit_idx = 3,
+		.bit_width = 1,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	},
+	[IMX95_CLK_DISPMIX_PIX_DI1_GATE] = {
+		.name = "lvds_di1_gate",
+		.parent_names = (const char *[]){ "ldb_pll_div7", },
+		.num_parents = 1,
+		.reg = 0,
+		.bit_idx = 4,
+		.bit_width = 1,
+		.type = CLK_GATE,
+		.flags = CLK_SET_RATE_PARENT,
+		.flags2 = CLK_GATE_SET_TO_DISABLE,
+	},
+};
+
+static const struct imx95_blk_ctl_dev_data lvds_csr_dev_data = {
+	.num_clks = ARRAY_SIZE(lvds_clk_dev_data),
+	.clk_dev_data = lvds_clk_dev_data,
+	.clk_reg_offset = 0,
+};
+
+static const struct imx95_blk_ctl_clk_dev_data dispmix_csr_clk_dev_data[] = {
+	[IMX95_CLK_DISPMIX_ENG0_SEL] = {
+		.name = "disp_engine0_sel",
+		.parent_names = (const char *[]){"videopll1", "dsi_pll", "ldb_pll_div7", },
+		.num_parents = 4,
+		.reg = 0,
+		.bit_idx = 0,
+		.bit_width = 2,
+		.type = CLK_MUX,
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
+	},
+	[IMX95_CLK_DISPMIX_ENG1_SEL] = {
+		.name = "disp_engine1_sel",
+		.parent_names = (const char *[]){"videopll1", "dsi_pll", "ldb_pll_div7", },
+		.num_parents = 4,
+		.reg = 0,
+		.bit_idx = 2,
+		.bit_width = 2,
+		.type = CLK_MUX,
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
+	}
+};
+
+static const struct imx95_blk_ctl_dev_data dispmix_csr_dev_data = {
+	.num_clks = ARRAY_SIZE(dispmix_csr_clk_dev_data),
+	.clk_dev_data = dispmix_csr_clk_dev_data,
+	.clk_reg_offset = 0,
+};
+
+static int imx95_bc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct imx95_blk_ctl_dev_data *bc_data;
+	struct imx95_blk_ctl *bc;
+	struct clk_hw_onecell_data *clk_hw_data;
+	struct clk_hw **hws;
+	void __iomem *base;
+	int i, ret;
+
+	bc = devm_kzalloc(dev, sizeof(*bc), GFP_KERNEL);
+	if (!bc)
+		return -ENOMEM;
+	bc->dev = dev;
+	dev_set_drvdata(&pdev->dev, bc);
+
+	spin_lock_init(&bc->lock);
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	bc->base = base;
+	bc->clk_apb = devm_clk_get(dev, NULL);
+	if (IS_ERR(bc->clk_apb))
+		return dev_err_probe(dev, PTR_ERR(bc->clk_apb), "failed to get APB clock\n");
+
+	ret = clk_prepare_enable(bc->clk_apb);
+	if (ret) {
+		dev_err(dev, "failed to enable apb clock: %d\n", ret);
+		return ret;
+	}
+
+	bc_data = of_device_get_match_data(dev);
+	if (!bc_data)
+		return devm_of_platform_populate(dev);
+
+	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, bc_data->num_clks),
+				   GFP_KERNEL);
+	if (!clk_hw_data)
+		return -ENOMEM;
+
+	if (bc_data->rpm_enabled)
+		pm_runtime_enable(&pdev->dev);
+
+	clk_hw_data->num = bc_data->num_clks;
+	hws = clk_hw_data->hws;
+
+	for (i = 0; i < bc_data->num_clks; i++) {
+		const struct imx95_blk_ctl_clk_dev_data *data = &bc_data->clk_dev_data[i];
+		void __iomem *reg = base + data->reg;
+
+		if (data->type == CLK_MUX) {
+			hws[i] = clk_hw_register_mux(dev, data->name, data->parent_names,
+						     data->num_parents, data->flags, reg,
+						     data->bit_idx, data->bit_width,
+						     data->flags2, &bc->lock);
+		} else if (data->type == CLK_DIVIDER) {
+			hws[i] = clk_hw_register_divider(dev, data->name, data->parent_names[0],
+							 data->flags, reg, data->bit_idx,
+							 data->bit_width, data->flags2, &bc->lock);
+		} else {
+			hws[i] = clk_hw_register_gate(dev, data->name, data->parent_names[0],
+						      data->flags, reg, data->bit_idx,
+						      data->flags2, &bc->lock);
+		}
+		if (IS_ERR(hws[i])) {
+			ret = PTR_ERR(hws[i]);
+			dev_err(dev, "failed to register: %s:%d\n", data->name, ret);
+			goto cleanup;
+		}
+	}
+
+	ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, clk_hw_data);
+	if (ret)
+		goto cleanup;
+
+	ret = devm_of_platform_populate(dev);
+	if (ret) {
+		of_clk_del_provider(dev->of_node);
+		goto cleanup;
+	}
+
+	if (pm_runtime_enabled(bc->dev))
+		clk_disable_unprepare(bc->clk_apb);
+
+	return 0;
+
+cleanup:
+	for (i = 0; i < bc_data->num_clks; i++) {
+		if (IS_ERR_OR_NULL(hws[i]))
+			continue;
+		clk_hw_unregister(hws[i]);
+	}
+
+	if (bc_data->rpm_enabled)
+		pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int imx95_bc_runtime_suspend(struct device *dev)
+{
+	struct imx95_blk_ctl *bc = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(bc->clk_apb);
+	return 0;
+}
+
+static int imx95_bc_runtime_resume(struct device *dev)
+{
+	struct imx95_blk_ctl *bc = dev_get_drvdata(dev);
+
+	return clk_prepare_enable(bc->clk_apb);
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int imx95_bc_suspend(struct device *dev)
+{
+	struct imx95_blk_ctl *bc = dev_get_drvdata(dev);
+	const struct imx95_blk_ctl_dev_data *bc_data;
+	int ret;
+
+	bc_data = of_device_get_match_data(dev);
+	if (!bc_data)
+		return 0;
+
+	if (bc_data->rpm_enabled) {
+		ret = pm_runtime_get_sync(bc->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(bc->dev);
+			return ret;
+		}
+	}
+
+	bc->clk_reg_restore = readl(bc->base + bc_data->clk_reg_offset);
+
+	return 0;
+}
+
+static int imx95_bc_resume(struct device *dev)
+{
+	struct imx95_blk_ctl *bc = dev_get_drvdata(dev);
+	const struct imx95_blk_ctl_dev_data *bc_data;
+
+	bc_data = of_device_get_match_data(dev);
+	if (!bc_data)
+		return 0;
+
+	writel(bc->clk_reg_restore, bc->base + bc_data->clk_reg_offset);
+
+	if (bc_data->rpm_enabled)
+		pm_runtime_put(bc->dev);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops imx95_bc_pm_ops = {
+	SET_RUNTIME_PM_OPS(imx95_bc_runtime_suspend, imx95_bc_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(imx95_bc_suspend, imx95_bc_resume)
+};
+
+static const struct of_device_id imx95_bc_of_match[] = {
+	{ .compatible = "nxp,imx95-camera-csr", .data = &camblk_dev_data },
+	{ .compatible = "nxp,imx95-display-master-csr", },
+	{ .compatible = "nxp,imx95-lvds-csr", .data = &lvds_csr_dev_data },
+	{ .compatible = "nxp,imx95-display-csr", .data = &dispmix_csr_dev_data },
+	{ .compatible = "nxp,imx95-vpu-csr", .data = &vpublk_dev_data },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx95_bc_of_match);
+
+static struct platform_driver imx95_bc_driver = {
+	.probe = imx95_bc_probe,
+	.driver = {
+		.name = "imx95-blk-ctl",
+		.of_match_table = imx95_bc_of_match,
+		.pm = &imx95_bc_pm_ops,
+	},
+};
+module_platform_driver(imx95_bc_driver);
+
+MODULE_DESCRIPTION("NXP i.MX95 blk ctl driver");
+MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
+MODULE_LICENSE("GPL");

-- 
2.37.1


^ permalink raw reply related

* [PATCH v6 3/4] dt-bindings: clock: support i.MX95 Display Master CSR module
From: Peng Fan (OSS) @ 2024-04-01 13:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Abel Vesa
  Cc: linux-clk, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan, Krzysztof Kozlowski
In-Reply-To: <20240401-imx95-blk-ctl-v6-0-84d4eca1e759@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

i.MX95 DISPLAY_MASTER_CSR includes registers to control DSI clock settings,
clock gating, and pixel link select. Add dt-schema for it.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 .../clock/nxp,imx95-display-master-csr.yaml        | 64 ++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-display-master-csr.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-display-master-csr.yaml
new file mode 100644
index 000000000000..07f7412e7658
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nxp,imx95-display-master-csr.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/nxp,imx95-display-master-csr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX95 Display Master Block Control
+
+maintainers:
+  - Peng Fan <peng.fan@nxp.com>
+
+properties:
+  compatible:
+    items:
+      - const: nxp,imx95-display-master-csr
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+    description:
+      The clock consumer should specify the desired clock by having the clock
+      ID in its "clocks" phandle cell. See
+      include/dt-bindings/clock/nxp,imx95-clock.h
+
+  mux-controller:
+    type: object
+    $ref: /schemas/mux/reg-mux.yaml
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - mux-controller
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    syscon@4c410000 {
+      compatible = "nxp,imx95-display-master-csr", "syscon";
+      reg = <0x4c410000 0x10000>;
+      #clock-cells = <1>;
+      clocks = <&scmi_clk 62>;
+      power-domains = <&scmi_devpd 3>;
+
+      mux: mux-controller {
+        compatible = "mmio-mux";
+        #mux-control-cells = <1>;
+        mux-reg-masks = <0x4 0x00000001>; /* Pixel_link_sel */
+        idle-states = <0>;
+      };
+    };
+...

-- 
2.37.1


^ permalink raw reply related

* [PATCH v6 2/4] dt-bindings: clock: support i.MX95 BLK CTL module
From: Peng Fan (OSS) @ 2024-04-01 13:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Abel Vesa
  Cc: linux-clk, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan, Krzysztof Kozlowski
In-Reply-To: <20240401-imx95-blk-ctl-v6-0-84d4eca1e759@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

i.MX95 includes BLK CTL module in several MIXes, such as VPU_CSR in
VPUMIX, CAMERA_CSR in CAMERAMIX and etc.

The BLK CTL module is used for various settings of a specific MIX, such
as clock, QoS and etc.

This patch is to add some BLK CTL modules that has clock features.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 .../bindings/clock/nxp,imx95-blk-ctl.yaml          | 56 ++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
new file mode 100644
index 000000000000..2dffc02dcd8b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/nxp,imx95-blk-ctl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX95 Block Control
+
+maintainers:
+  - Peng Fan <peng.fan@nxp.com>
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - nxp,imx95-lvds-csr
+          - nxp,imx95-display-csr
+          - nxp,imx95-camera-csr
+          - nxp,imx95-vpu-csr
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+    description:
+      The clock consumer should specify the desired clock by having the clock
+      ID in its "clocks" phandle cell. See
+      include/dt-bindings/clock/nxp,imx95-clock.h
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    syscon@4c410000 {
+      compatible = "nxp,imx95-vpu-csr", "syscon";
+      reg = <0x4c410000 0x10000>;
+      #clock-cells = <1>;
+      clocks = <&scmi_clk 114>;
+      power-domains = <&scmi_devpd 21>;
+    };
+...

-- 
2.37.1


^ permalink raw reply related

* [PATCH v6 1/4] dt-bindings: clock: add i.MX95 clock header
From: Peng Fan (OSS) @ 2024-04-01 13:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Abel Vesa
  Cc: linux-clk, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan
In-Reply-To: <20240401-imx95-blk-ctl-v6-0-84d4eca1e759@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

Add clock header for i.MX95 BLK CTL modules

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 include/dt-bindings/clock/nxp,imx95-clock.h | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/include/dt-bindings/clock/nxp,imx95-clock.h b/include/dt-bindings/clock/nxp,imx95-clock.h
new file mode 100644
index 000000000000..782662c3e740
--- /dev/null
+++ b/include/dt-bindings/clock/nxp,imx95-clock.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/*
+ * Copyright 2024 NXP
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX95_H
+#define __DT_BINDINGS_CLOCK_IMX95_H
+
+#define IMX95_CLK_VPUBLK_WAVE			0
+#define IMX95_CLK_VPUBLK_JPEG_ENC		1
+#define IMX95_CLK_VPUBLK_JPEG_DEC		2
+
+#define IMX95_CLK_CAMBLK_CSI2_FOR0		0
+#define IMX95_CLK_CAMBLK_CSI2_FOR1		1
+#define IMX95_CLK_CAMBLK_ISP_AXI		2
+#define IMX95_CLK_CAMBLK_ISP_PIXEL		3
+#define IMX95_CLK_CAMBLK_ISP			4
+
+#define IMX95_CLK_DISPMIX_LVDS_PHY_DIV		0
+#define IMX95_CLK_DISPMIX_LVDS_CH0_GATE		1
+#define IMX95_CLK_DISPMIX_LVDS_CH1_GATE		2
+#define IMX95_CLK_DISPMIX_PIX_DI0_GATE		3
+#define IMX95_CLK_DISPMIX_PIX_DI1_GATE		4
+
+#define IMX95_CLK_DISPMIX_ENG0_SEL		0
+#define IMX95_CLK_DISPMIX_ENG1_SEL		1
+
+#endif	/* __DT_BINDINGS_CLOCK_IMX95_H */

-- 
2.37.1


^ permalink raw reply related

* [PATCH v6 0/4] Add support i.MX95 BLK CTL module clock features
From: Peng Fan (OSS) @ 2024-04-01 13:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Abel Vesa
  Cc: linux-clk, devicetree, imx, linux-arm-kernel, linux-kernel,
	Peng Fan, Krzysztof Kozlowski

i.MX95's several MIXes has BLK CTL module which could be used for
clk settings, QoS settings, Misc settings for a MIX. This patchset
is to add the clk feature support, including dt-bindings

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Changes in v6:
- Put the header as 1st patch, and drop the macro that counting the clks
- Add R-b for patch 2&3
- Drop of_match_ptr in patch 4
- Link to v5: https://lore.kernel.org/r/20240324-imx95-blk-ctl-v5-0-7a706174078a@nxp.com

Changes in v5:
- Merge bindings except the one has mux-controller
- Separate clock ID headers in a separate patch per Rob's comments
- Link to v4: https://lore.kernel.org/r/20240314-imx95-blk-ctl-v4-0-d23de23b6ff2@nxp.com

Changes in v4:
- Separate binding doc for each modules, I still keep the syscon as node
name, because the module is not just for clock
- Pass dt-schema check
- Update node compatibles
- Link to v3: https://lore.kernel.org/r/20240228-imx95-blk-ctl-v3-0-40ceba01a211@nxp.com

Changes in v3:
- Correct example node compatible string
- Pass "make ARCH=arm64 DT_CHECKER_FLAGS=-m -j32 dt_binding_check"
- Link to v2: https://lore.kernel.org/r/20240228-imx95-blk-ctl-v2-0-ffb7eefb6dcd@nxp.com

Changes in v2:
- Correct example node compatible string
- Link to v1: https://lore.kernel.org/r/20240228-imx95-blk-ctl-v1-0-9b5ae3c14d83@nxp.com

---
Peng Fan (4):
      dt-bindings: clock: add i.MX95 clock header
      dt-bindings: clock: support i.MX95 BLK CTL module
      dt-bindings: clock: support i.MX95 Display Master CSR module
      clk: imx: add i.MX95 BLK CTL clk driver

 .../bindings/clock/nxp,imx95-blk-ctl.yaml          |  56 +++
 .../clock/nxp,imx95-display-master-csr.yaml        |  64 +++
 drivers/clk/imx/Kconfig                            |   7 +
 drivers/clk/imx/Makefile                           |   1 +
 drivers/clk/imx/clk-imx95-blk-ctl.c                | 438 +++++++++++++++++++++
 include/dt-bindings/clock/nxp,imx95-clock.h        |  28 ++
 6 files changed, 594 insertions(+)
---
base-commit: c9c32620af65fee2b1ac8390fe1349b33f9d0888
change-id: 20240228-imx95-blk-ctl-9ef8c1fc4c22

Best regards,
-- 
Peng Fan <peng.fan@nxp.com>


^ permalink raw reply

* [PATCH v2 2/2] ASoC: dt-bindings: fsl-asoc-card: convert to YAML
From: Shengjiu Wang @ 2024-04-01 12:54 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	shengjiu.wang, linux-sound, devicetree, linux-kernel, shawnguo,
	s.hauer, kernel, festevam, imx, linux-arm-kernel
In-Reply-To: <1711976056-19884-1-git-send-email-shengjiu.wang@nxp.com>

Convert the fsl-asoc-card binding to YAML.

When testing dtbs_check, found below compatible strings
are not listed in document:

fsl,imx-sgtl5000
fsl,imx53-cpuvo-sgtl5000
fsl,imx51-babbage-sgtl5000
fsl,imx53-m53evk-sgtl5000
fsl,imx53-qsb-sgtl5000
fsl,imx53-voipac-sgtl5000
fsl,imx6-armadeus-sgtl5000
fsl,imx6-rex-sgtl5000
fsl,imx6-sabreauto-cs42888
fsl,imx6-wandboard-sgtl5000
fsl,imx6dl-nit6xlite-sgtl5000
fsl,imx6q-ba16-sgtl5000
fsl,imx6q-nitrogen6_max-sgtl5000
fsl,imx6q-nitrogen6_som2-sgtl5000
fsl,imx6q-nitrogen6x-sgtl5000
fsl,imx6q-sabrelite-sgtl5000
fsl,imx6q-sabresd-wm8962
fsl,imx6q-udoo-ac97
fsl,imx6q-ventana-sgtl5000
fsl,imx6sl-evk-wm8962
fsl,imx6sx-sdb-mqs
fsl,imx6sx-sdb-wm8962
fsl,imx7d-evk-wm8960
karo,tx53-audio-sgtl5000
tq,imx53-mba53-sgtl5000

So add them in yaml file to pass the test.

Also correct the 'dai-format' to 'format' in document.

For 'audio-routing', the items are not listed. Because
this fsl-asoc-card is generic driver, which supports several
codecs, if list all the items, there will be a long list.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
 .../bindings/sound/fsl-asoc-card.txt          | 117 -----------
 .../bindings/sound/fsl-asoc-card.yaml         | 195 ++++++++++++++++++
 2 files changed, 195 insertions(+), 117 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
 create mode 100644 Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
deleted file mode 100644
index 4e8dbc5abfd1..000000000000
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ /dev/null
@@ -1,117 +0,0 @@
-Freescale Generic ASoC Sound Card with ASRC support
-
-The Freescale Generic ASoC Sound Card can be used, ideally, for all Freescale
-SoCs connecting with external CODECs.
-
-The idea of this generic sound card is a bit like ASoC Simple Card. However,
-for Freescale SoCs (especially those released in recent years), most of them
-have ASRC (Documentation/devicetree/bindings/sound/fsl,asrc.txt) inside. And
-this is a specific feature that might be painstakingly controlled and merged
-into the Simple Card.
-
-So having this generic sound card allows all Freescale SoC users to benefit
-from the simplification of a new card support and the capability of the wide
-sample rates support through ASRC.
-
-Note: The card is initially designed for those sound cards who use AC'97, I2S
-      and PCM DAI formats. However, it'll be also possible to support those non
-      AC'97/I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as
-      long as the driver has been properly upgraded.
-
-
-The compatible list for this generic sound card currently:
- "fsl,imx-audio-ac97"
-
- "fsl,imx-audio-cs42888"
-
- "fsl,imx-audio-cs427x"
- (compatible with CS4271 and CS4272)
-
- "fsl,imx-audio-wm8962"
-
- "fsl,imx-audio-sgtl5000"
- (compatible with Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt)
-
- "fsl,imx-audio-wm8960"
-
- "fsl,imx-audio-mqs"
-
- "fsl,imx-audio-wm8524"
-
- "fsl,imx-audio-tlv320aic32x4"
-
- "fsl,imx-audio-tlv320aic31xx"
-
- "fsl,imx-audio-si476x"
-
- "fsl,imx-audio-wm8958"
-
- "fsl,imx-audio-nau8822"
-
-Required properties:
-
-  - compatible		: Contains one of entries in the compatible list.
-
-  - model		: The user-visible name of this sound complex
-
-  - audio-cpu		: The phandle of an CPU DAI controller
-
-  - audio-codec		: The phandle of an audio codec
-
-Optional properties:
-
-  - audio-asrc		: The phandle of ASRC. It can be absent if there's no
-			  need to add ASRC support via DPCM.
-
-  - audio-routing	: A list of the connections between audio components.
-			  Each entry is a pair of strings, the first being the
-			  connection's sink, the second being the connection's
-			  source. There're a few pre-designed board connectors:
-			   * Line Out Jack
-			   * Line In Jack
-			   * Headphone Jack
-			   * Mic Jack
-			   * Ext Spk
-			   * AMIC (stands for Analog Microphone Jack)
-			   * DMIC (stands for Digital Microphone Jack)
-
-			  Note: The "Mic Jack" and "AMIC" are redundant while
-			        coexisting in order to support the old bindings
-				of wm8962 and sgtl5000.
-
-  - hp-det-gpio		: The GPIO that detect headphones are plugged in
-  - mic-det-gpio	: The GPIO that detect microphones are plugged in
-  - bitclock-master	: Indicates dai-link bit clock master; for details see simple-card.yaml.
-  - frame-master	: Indicates dai-link frame master; for details see simple-card.yaml.
-  - dai-format		: audio format, for details see simple-card.yaml.
-  - frame-inversion	: dai-link uses frame clock inversion, for details see simple-card.yaml.
-  - bitclock-inversion	: dai-link uses bit clock inversion, for details see simple-card.yaml.
-  - mclk-id		: main clock id, specific for each card configuration.
-
-Optional unless SSI is selected as a CPU DAI:
-
-  - mux-int-port	: The internal port of the i.MX audio muxer (AUDMUX)
-
-  - mux-ext-port	: The external port of the i.MX audio muxer
-
-Example:
-sound-cs42888 {
-	compatible = "fsl,imx-audio-cs42888";
-	model = "cs42888-audio";
-	audio-cpu = <&esai>;
-	audio-asrc = <&asrc>;
-	audio-codec = <&cs42888>;
-	audio-routing =
-		"Line Out Jack", "AOUT1L",
-		"Line Out Jack", "AOUT1R",
-		"Line Out Jack", "AOUT2L",
-		"Line Out Jack", "AOUT2R",
-		"Line Out Jack", "AOUT3L",
-		"Line Out Jack", "AOUT3R",
-		"Line Out Jack", "AOUT4L",
-		"Line Out Jack", "AOUT4R",
-		"AIN1L", "Line In Jack",
-		"AIN1R", "Line In Jack",
-		"AIN2L", "Line In Jack",
-		"AIN2R", "Line In Jack";
-};
diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml b/Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml
new file mode 100644
index 000000000000..42ca39eebd49
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml
@@ -0,0 +1,195 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl-asoc-card.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale Generic ASoC Sound Card with ASRC support
+
+description:
+  The Freescale Generic ASoC Sound Card can be used, ideally,
+  for all Freescale SoCs connecting with external CODECs.
+
+  The idea of this generic sound card is a bit like ASoC Simple Card.
+  However, for Freescale SoCs (especially those released in recent years),
+  most of them have ASRC inside. And this is a specific feature that might
+  be painstakingly controlled and merged into the Simple Card.
+
+  So having this generic sound card allows all Freescale SoC users to
+  benefit from the simplification of a new card support and the capability
+  of the wide sample rates support through ASRC.
+
+  Note, The card is initially designed for those sound cards who use AC'97, I2S
+  and PCM DAI formats. However, it'll be also possible to support those non
+  AC'97/I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as
+  long as the driver has been properly upgraded.
+
+maintainers:
+  - Shengjiu Wang <shengjiu.wang@nxp.com>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - fsl,imx-sgtl5000
+              - fsl,imx53-cpuvo-sgtl5000
+              - fsl,imx51-babbage-sgtl5000
+              - fsl,imx53-m53evk-sgtl5000
+              - fsl,imx53-qsb-sgtl5000
+              - fsl,imx53-voipac-sgtl5000
+              - fsl,imx6-armadeus-sgtl5000
+              - fsl,imx6-rex-sgtl5000
+              - fsl,imx6-sabreauto-cs42888
+              - fsl,imx6-wandboard-sgtl5000
+              - fsl,imx6dl-nit6xlite-sgtl5000
+              - fsl,imx6q-ba16-sgtl5000
+              - fsl,imx6q-nitrogen6_max-sgtl5000
+              - fsl,imx6q-nitrogen6_som2-sgtl5000
+              - fsl,imx6q-nitrogen6x-sgtl5000
+              - fsl,imx6q-sabrelite-sgtl5000
+              - fsl,imx6q-sabresd-wm8962
+              - fsl,imx6q-udoo-ac97
+              - fsl,imx6q-ventana-sgtl5000
+              - fsl,imx6sl-evk-wm8962
+              - fsl,imx6sx-sdb-mqs
+              - fsl,imx6sx-sdb-wm8962
+              - fsl,imx7d-evk-wm8960
+              - karo,tx53-audio-sgtl5000
+              - tq,imx53-mba53-sgtl5000
+          - enum:
+              - fsl,imx-audio-ac97
+              - fsl,imx-audio-cs42888
+              - fsl,imx-audio-mqs
+              - fsl,imx-audio-sgtl5000
+              - fsl,imx-audio-wm8960
+              - fsl,imx-audio-wm8962
+      - items:
+          - enum:
+              - fsl,imx-audio-ac97
+              - fsl,imx-audio-cs42888
+              - fsl,imx-audio-cs427x
+              - fsl,imx-audio-mqs
+              - fsl,imx-audio-nau8822
+              - fsl,imx-audio-sgtl5000
+              - fsl,imx-audio-si476x
+              - fsl,imx-audio-tlv320aic31xx
+              - fsl,imx-audio-tlv320aic32x4
+              - fsl,imx-audio-wm8524
+              - fsl,imx-audio-wm8960
+              - fsl,imx-audio-wm8962
+              - fsl,imx-audio-wm8958
+
+  model:
+    $ref: /schemas/types.yaml#/definitions/string
+    description: The user-visible name of this sound complex
+
+  audio-asrc:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of ASRC. It can be absent if there's no
+      need to add ASRC support via DPCM.
+
+  audio-codec:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of an audio codec
+
+  audio-cpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of an CPU DAI controller
+
+  audio-routing:
+    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+    description:
+      A list of the connections between audio components. Each entry is a
+      pair of strings, the first being the connection's sink, the second
+      being the connection's source. There're a few pre-designed board
+      connectors. "AMIC" stands for Analog Microphone Jack.
+      "DMIC" stands for Digital Microphone Jack. The "Mic Jack" and "AMIC"
+      are redundant while coexisting in order to support the old bindings
+      of wm8962 and sgtl5000.
+
+  hp-det-gpio:
+    deprecated: true
+    maxItems: 1
+    description: The GPIO that detect headphones are plugged in
+
+  hp-det-gpios:
+    maxItems: 1
+    description: The GPIO that detect headphones are plugged in
+
+  mic-det-gpio:
+    deprecated: true
+    maxItems: 1
+    description: The GPIO that detect microphones are plugged in
+
+  mic-det-gpios:
+    maxItems: 1
+    description: The GPIO that detect microphones are plugged in
+
+  bitclock-master:
+    $ref: simple-card.yaml#/definitions/bitclock-master
+    description: Indicates dai-link bit clock master.
+
+  frame-master:
+    $ref: simple-card.yaml#/definitions/frame-master
+    description: Indicates dai-link frame master.
+
+  format:
+    $ref: simple-card.yaml#/definitions/format
+    description: audio format.
+
+  frame-inversion:
+    $ref: simple-card.yaml#/definitions/frame-inversion
+    description: dai-link uses frame clock inversion.
+
+  bitclock-inversion:
+    $ref: simple-card.yaml#/definitions/bitclock-inversion
+    description: dai-link uses bit clock inversion.
+
+  mclk-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: main clock id, specific for each card configuration.
+
+  mux-int-port:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2, 7]
+    description: The internal port of the i.MX audio muxer (AUDMUX)
+
+  mux-ext-port:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [3, 4, 5, 6]
+    description: The external port of the i.MX audio muxer
+
+  ssi-controller:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of an CPU DAI controller
+
+required:
+  - compatible
+  - model
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    sound-cs42888 {
+        compatible = "fsl,imx-audio-cs42888";
+        model = "cs42888-audio";
+        audio-cpu = <&esai>;
+        audio-asrc = <&asrc>;
+        audio-codec = <&cs42888>;
+        audio-routing =
+             "Line Out Jack", "AOUT1L",
+             "Line Out Jack", "AOUT1R",
+             "Line Out Jack", "AOUT2L",
+             "Line Out Jack", "AOUT2R",
+             "Line Out Jack", "AOUT3L",
+             "Line Out Jack", "AOUT3R",
+             "Line Out Jack", "AOUT4L",
+             "Line Out Jack", "AOUT4R",
+             "AIN1L", "Line In Jack",
+             "AIN1R", "Line In Jack",
+             "AIN2L", "Line In Jack",
+             "AIN2R", "Line In Jack";
+    };
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 1/2] ARM: dts: imx6sx-nitrogen6sx: drop incorrect cpu-dai property
From: Shengjiu Wang @ 2024-04-01 12:54 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	shengjiu.wang, linux-sound, devicetree, linux-kernel, shawnguo,
	s.hauer, kernel, festevam, imx, linux-arm-kernel
In-Reply-To: <1711976056-19884-1-git-send-email-shengjiu.wang@nxp.com>

drop incorrect cpu-dai property, change it to ssi-controller

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
 arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts b/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts
index cd9cbc9ccc9e..b82d91a7d76d 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts
@@ -83,7 +83,7 @@ reg_wlan: regulator-wlan {
 	sound {
 		compatible = "fsl,imx-audio-sgtl5000";
 		model = "imx6sx-nitrogen6sx-sgtl5000";
-		cpu-dai = <&ssi1>;
+		ssi-controller = <&ssi1>;
 		audio-codec = <&codec>;
 		audio-routing =
 			"MIC_IN", "Mic Jack",
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 0/2] ASoC: dt-bindings: convert fsl-asoc-card.txt to YAML
From: Shengjiu Wang @ 2024-04-01 12:54 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, krzysztof.kozlowski+dt, conor+dt,
	shengjiu.wang, linux-sound, devicetree, linux-kernel, shawnguo,
	s.hauer, kernel, festevam, imx, linux-arm-kernel

Convert fsl-asoc-card.txt to YAML. In order to pass the checking,
add some used compatible string from devicetree.

change cpu-dai in imx6sx-nitrogen6sx to ssi-controller.

changes in v2:
- update commit message for reason why add compatible strings
  which are not in txt file.
- add deprecated
- add $ref for bitclock-master and others.

Shengjiu Wang (2):
  ARM: dts: imx6sx-nitrogen6sx: drop incorrect cpu-dai property
  ASoC: dt-bindings: fsl-asoc-card: convert to YAML

 .../bindings/sound/fsl-asoc-card.txt          | 117 -----------
 .../bindings/sound/fsl-asoc-card.yaml         | 195 ++++++++++++++++++
 .../boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts   |   2 +-
 3 files changed, 196 insertions(+), 118 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
 create mode 100644 Documentation/devicetree/bindings/sound/fsl-asoc-card.yaml

-- 
2.34.1


^ permalink raw reply

* Re: [PATCH v3 1/2] dt-bindings: arm: qcom: Document the Samsung Galaxy Z Fold5
From: Rob Herring @ 2024-04-01 13:05 UTC (permalink / raw)
  To: Alexandru Marc Serdeliuc
  Cc: devicetree, linux-arm-msm, Bjorn Andersson, linux-kernel,
	Conor Dooley, Krzysztof Kozlowski, Konrad Dybcio
In-Reply-To: <20240331-samsung-galaxy-zfold5-q5q-v3-1-17ae8d0a9fba@yahoo.com>


On Sun, 31 Mar 2024 12:56:39 +0200, Alexandru Marc Serdeliuc wrote:
> This documents Samsung Galaxy Z Fold5 (samsung,q5q)
> which is a foldable phone by Samsung based on the sm8550 SoC.
> 
> Signed-off-by: Alexandru Marc Serdeliuc <serdeliuk@yahoo.com>
> ---
>  Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh@kernel.org>


^ permalink raw reply

* Re: [PATCH v5 1/2] dt-bindings: backlight: Add Texas Instruments LM3509
From: Rob Herring @ 2024-04-01 13:03 UTC (permalink / raw)
  To: Patrick Gansterer
  Cc: dri-devel, linux-leds, devicetree, linux-kernel, linux-fbdev,
	Lee Jones, Daniel Thompson, Jingoo Han, Pavel Machek,
	Krzysztof Kozlowski, Conor Dooley, Helge Deller, Sam Ravnborg,
	Krzysztof Kozlowski
In-Reply-To: <20240330145931.729116-2-paroga@paroga.com>

On Sat, Mar 30, 2024 at 03:59:24PM +0100, Patrick Gansterer wrote:
> Add Device Tree bindings for Texas Instruments LM3509 - a
> High Efficiency Boost for White LED's and/or OLED Displays
> 
> Signed-off-by: Patrick Gansterer <paroga@paroga.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
> ---
>  .../bindings/leds/backlight/ti,lm3509.yaml    | 139 ++++++++++++++++++
>  1 file changed, 139 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/leds/backlight/ti,lm3509.yaml
> 
> diff --git a/Documentation/devicetree/bindings/leds/backlight/ti,lm3509.yaml b/Documentation/devicetree/bindings/leds/backlight/ti,lm3509.yaml
> new file mode 100644
> index 000000000000..b67f67648852
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/backlight/ti,lm3509.yaml
> @@ -0,0 +1,139 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/leds/backlight/ti,lm3509.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: TI LM3509 High Efficiency Boost for White LED's and/or OLED Displays
> +
> +maintainers:
> +  - Patrick Gansterer <paroga@paroga.com>
> +
> +description:
> +  The LM3509 current mode boost converter offers two separate outputs.
> +  https://www.ti.com/product/LM3509
> +
> +properties:
> +  compatible:
> +    const: ti,lm3509
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#address-cells":
> +    const: 1
> +
> +  "#size-cells":
> +    const: 0
> +
> +  reset-gpios:
> +    maxItems: 1
> +
> +  ti,brightness-rate-of-change-us:
> +    description: Brightness Rate of Change in microseconds.
> +    enum: [51, 13000, 26000, 52000]
> +
> +  ti,oled-mode:
> +    description: Enable OLED mode.
> +    type: boolean
> +
> +patternProperties:
> +  "^led@[01]$":
> +    type: object
> +    description: Properties for a string of connected LEDs.
> +
> +    allOf:

You don't need allOf here.

> +      - $ref: common.yaml#
> +
> +    properties:
> +      reg:
> +        description:
> +          The control register that is used to program the two current sinks.
> +          The LM3509 has two registers (BMAIN and BSUB) and are represented
> +          as 0 or 1 in this property. The two current sinks can be controlled
> +          independently with both registers, or register BMAIN can be
> +          configured to control both sinks with the led-sources property.
> +        minimum: 0
> +        maximum: 1
> +
> +      label: true
> +
> +      led-sources:
> +        allOf:

Or here.

> +          - minItems: 1
> +            maxItems: 2
> +            items:
> +              minimum: 0
> +              maximum: 1

^ permalink raw reply

* [PATCH v2 2/2] arm64: dts: qcom: sm8150: Add video clock controller node
From: Satya Priya Kakitapalli @ 2024-04-01 11:14 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Turquette, Stephen Boyd
  Cc: Dmitry Baryshkov, Ajit Pandey, Imran Shaik, Taniya Das,
	Jagadeesh Kona, linux-arm-msm, devicetree, linux-kernel,
	linux-clk, Satya Priya Kakitapalli
In-Reply-To: <20240401-videocc-sm8150-dt-node-v2-0-3b87cd2add96@quicinc.com>

Add device node for video clock controller on Qualcomm
SM8150 platform.

Signed-off-by: Satya Priya Kakitapalli <quic_skakitap@quicinc.com>
---
 arch/arm64/boot/dts/qcom/sa8155p.dtsi |  4 ++++
 arch/arm64/boot/dts/qcom/sm8150.dtsi  | 13 +++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sa8155p.dtsi b/arch/arm64/boot/dts/qcom/sa8155p.dtsi
index ffb7ab695213..9e70effc72e1 100644
--- a/arch/arm64/boot/dts/qcom/sa8155p.dtsi
+++ b/arch/arm64/boot/dts/qcom/sa8155p.dtsi
@@ -38,3 +38,7 @@ &rpmhpd {
 	 */
 	compatible = "qcom,sa8155p-rpmhpd";
 };
+
+&videocc {
+	power-domains = <&rpmhpd SA8155P_CX>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index a35c0852b5a1..56694efa0c33 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -14,6 +14,7 @@
 #include <dt-bindings/clock/qcom,dispcc-sm8150.h>
 #include <dt-bindings/clock/qcom,gcc-sm8150.h>
 #include <dt-bindings/clock/qcom,gpucc-sm8150.h>
+#include <dt-bindings/clock/qcom,videocc-sm8150.h>
 #include <dt-bindings/interconnect/qcom,osm-l3.h>
 #include <dt-bindings/interconnect/qcom,sm8150.h>
 #include <dt-bindings/thermal/thermal.h>
@@ -3715,6 +3716,18 @@ usb_2_dwc3: usb@a800000 {
 			};
 		};
 
+		videocc: clock-controller@ab00000 {
+			compatible = "qcom,sm8150-videocc";
+			reg = <0 0x0ab00000 0 0x10000>;
+			clocks = <&gcc GCC_VIDEO_AHB_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "iface", "bi_tcxo";
+			power-domains = <&rpmhpd SM8150_MMCX>;
+		        #clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
 		camnoc_virt: interconnect@ac00000 {
 			compatible = "qcom,sm8150-camnoc-virt";
 			reg = <0 0x0ac00000 0 0x1000>;

-- 
2.25.1


^ permalink raw reply related

* [PATCH v2 1/2] dt-bindings: clock: qcom: Update SM8150 videocc bindings
From: Satya Priya Kakitapalli @ 2024-04-01 11:14 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Turquette, Stephen Boyd
  Cc: Dmitry Baryshkov, Ajit Pandey, Imran Shaik, Taniya Das,
	Jagadeesh Kona, linux-arm-msm, devicetree, linux-kernel,
	linux-clk, Satya Priya Kakitapalli
In-Reply-To: <20240401-videocc-sm8150-dt-node-v2-0-3b87cd2add96@quicinc.com>

Update the clocks list for SM8150 to add both AHB and XO clocks,
as it needs both of them.

Fixes: 35d26e9292e2 ("dt-bindings: clock: Add YAML schemas for the QCOM VIDEOCC clock bindings")
Signed-off-by: Satya Priya Kakitapalli <quic_skakitap@quicinc.com>
---
 .../devicetree/bindings/clock/qcom,videocc.yaml         | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,videocc.yaml
index 6999e36ace1b..68bac801adb0 100644
--- a/Documentation/devicetree/bindings/clock/qcom,videocc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,videocc.yaml
@@ -75,7 +75,6 @@ allOf:
           enum:
             - qcom,sc7180-videocc
             - qcom,sdm845-videocc
-            - qcom,sm8150-videocc
     then:
       properties:
         clocks:
@@ -101,6 +100,22 @@ allOf:
             - const: bi_tcxo
             - const: bi_tcxo_ao
 
+  - if:
+      properties:
+        compatible:
+          enum:
+            - qcom,sm8150-videocc
+    then:
+      properties:
+        clocks:
+          items:
+            - description: AHB
+            - description: Board XO source
+        clock-names:
+          items:
+            - const: iface
+            - const: bi_tcxo
+
   - if:
       properties:
         compatible:

-- 
2.25.1


^ permalink raw reply related

* [PATCH v2 0/2] Add DT support for video clock controller on SM8150
From: Satya Priya Kakitapalli @ 2024-04-01 11:14 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Turquette, Stephen Boyd
  Cc: Dmitry Baryshkov, Ajit Pandey, Imran Shaik, Taniya Das,
	Jagadeesh Kona, linux-arm-msm, devicetree, linux-kernel,
	linux-clk, Satya Priya Kakitapalli

Signed-off-by: Satya Priya Kakitapalli <quic_skakitap@quicinc.com>
---
Changes in v2:
- As per Dmitry's comments, there is no need to update to index based
  lookup for already existing drivers, hence keeping clock-names property.
- Updated the videocc bindings to add AHB clock for the sm8150 platform.
- Link to v1: https://lore.kernel.org/r/20240313-videocc-sm8150-dt-node-v1-0-ae8ec3c822c2@quicinc.com

---
Satya Priya Kakitapalli (2):
      dt-bindings: clock: qcom: Update SM8150 videocc bindings
      arm64: dts: qcom: sm8150: Add video clock controller node

 .../devicetree/bindings/clock/qcom,videocc.yaml         | 17 ++++++++++++++++-
 arch/arm64/boot/dts/qcom/sa8155p.dtsi                   |  4 ++++
 arch/arm64/boot/dts/qcom/sm8150.dtsi                    | 13 +++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)
---
base-commit: 8ffc8b1bbd505e27e2c8439d326b6059c906c9dd
change-id: 20240308-videocc-sm8150-dt-node-6f163b492f7c

Best regards,
-- 
Satya Priya Kakitapalli <quic_skakitap@quicinc.com>


^ permalink raw reply

* Re: [PATCH v7 2/2] dmaengine: Loongson1: Add Loongson-1 APB DMA driver
From: Keguang Zhang @ 2024-04-01 11:09 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Vinod Koul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-mips, dmaengine, devicetree, linux-kernel
In-Reply-To: <CAAhV-H63wMMhVng=kn+XOHFL8sTchtGAMae0v50FEN6TO1kAhw@mail.gmail.com>

On Mon, Apr 1, 2024 at 5:06 PM Huacai Chen <chenhuacai@kernel.org> wrote:
>
> On Mon, Apr 1, 2024 at 10:45 AM Keguang Zhang <keguang.zhang@gmail.com> wrote:
> >
> > Hi Huacai,
> >
> > On Sat, Mar 30, 2024 at 9:59 PM Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > > Hi, Keguang,
> > >
> > > On Fri, Mar 29, 2024 at 7:28 PM Keguang Zhang via B4 Relay
> > > <devnull+keguang.zhang.gmail.com@kernel.org> wrote:
> > > >
> > > > From: Keguang Zhang <keguang.zhang@gmail.com>
> > > >
> > > > This patch adds APB DMA driver for Loongson-1 SoCs.
> > > >
> > > > Signed-off-by: Keguang Zhang <keguang.zhang@gmail.com>
> > > > ---
> > > > Changes in v7:
> > > > - Change the comptible to 'loongson,ls1*-apbdma'
> > > > - Update Kconfig and Makefile accordingly
> > > > - Rename the file to loongson1-apb-dma.c to keep the consistency
> > > >
> > > > Changes in v6:
> > > > - Implement .device_prep_dma_cyclic for Loongson1 audio driver,
> > > > - as well as .device_pause and .device_resume.
> > > > - Set the limitation LS1X_DMA_MAX_DESC and put all descriptors
> > > > - into one page to save memory
> > > > - Move dma_pool_zalloc() into ls1x_dma_alloc_desc()
> > > > - Drop dma_slave_config structure
> > > > - Use .remove_new instead of .remove
> > > > - Use KBUILD_MODNAME for the driver name
> > > > - Improve the debug information
> > > >
> > > > Changes in v5:
> > > > - Add DT support
> > > > - Use DT data instead of platform data
> > > > - Use chan_id of struct dma_chan instead of own id
> > > > - Use of_dma_xlate_by_chan_id() instead of ls1x_dma_filter()
> > > > - Update the author information to my official name
> > > >
> > > > Changes in v4:
> > > > - Use dma_slave_map to find the proper channel.
> > > > - Explicitly call devm_request_irq() and tasklet_kill().
> > > > - Fix namespace issue.
> > > > - Some minor fixes and cleanups.
> > > >
> > > > Changes in v3:
> > > > - Rename ls1x_dma_filter_fn to ls1x_dma_filter.
> > > >
> > > > Changes in v2:
> > > > - Change the config from 'DMA_LOONGSON1' to 'LOONGSON1_DMA',
> > > > - and rearrange it in alphabetical order in Kconfig and Makefile.
> > > > - Fix comment style.
> > > > ---
> > > >  drivers/dma/Kconfig             |   9 +
> > > >  drivers/dma/Makefile            |   1 +
> > > >  drivers/dma/loongson1-apb-dma.c | 665 ++++++++++++++++++++++++++++++++++++++++
> > > >  3 files changed, 675 insertions(+)
> > > >
> > > > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> > > > index 002a5ec80620..f7b06c4cdf3f 100644
> > > > --- a/drivers/dma/Kconfig
> > > > +++ b/drivers/dma/Kconfig
> > > > @@ -369,6 +369,15 @@ config K3_DMA
> > > >           Support the DMA engine for Hisilicon K3 platform
> > > >           devices.
> > > >
> > > > +config LOONGSON1_APB_DMA
> > > > +       tristate "Loongson1 APB DMA support"
> > > > +       depends on MACH_LOONGSON32 || COMPILE_TEST
> > > > +       select DMA_ENGINE
> > > > +       select DMA_VIRTUAL_CHANNELS
> > > > +       help
> > > > +         This selects support for the APB DMA controller in Loongson1 SoCs,
> > > > +         which is required by Loongson1 NAND and audio support.
> > > Why not rename to LS1X_APB_DMA and put it just before LS2X_APB_DMA
> > > (and also the driver file name)?
> > >
> > So far all Kconfig entries of Loongson-1 drivers are named with the
> > keyword "LOONGSON1".
> > The same is true for these file names.
> > Therefore, I need to keep the consistency.
> But I see LS1X_IRQ in drivers/irqchip/Kconfig
>
Indeed, that's an exception, which was submitted by Jiaxun several years ago.
Actually, most drivers of Loongson family use the keyword "LOONGSON"
for Kconfig and "loongson" for filename.
Thus I take this keywork as the naming convention.

> Huacai
>
> >
> >
> > > Huacai
> > >
> > > > +
> > > >  config LPC18XX_DMAMUX
> > > >         bool "NXP LPC18xx/43xx DMA MUX for PL080"
> > > >         depends on ARCH_LPC18XX || COMPILE_TEST
> > > > diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> > > > index dfd40d14e408..b26f6677978a 100644
> > > > --- a/drivers/dma/Makefile
> > > > +++ b/drivers/dma/Makefile
> > > > @@ -47,6 +47,7 @@ obj-$(CONFIG_INTEL_IDMA64) += idma64.o
> > > >  obj-$(CONFIG_INTEL_IOATDMA) += ioat/
> > > >  obj-y += idxd/
> > > >  obj-$(CONFIG_K3_DMA) += k3dma.o
> > > > +obj-$(CONFIG_LOONGSON1_APB_DMA) += loongson1-apb-dma.o
> > > >  obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
> > > >  obj-$(CONFIG_LS2X_APB_DMA) += ls2x-apb-dma.o
> > > >  obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
> > > > diff --git a/drivers/dma/loongson1-apb-dma.c b/drivers/dma/loongson1-apb-dma.c
> > > > new file mode 100644
> > > > index 000000000000..d474a2601e6e
> > > > --- /dev/null
> > > > +++ b/drivers/dma/loongson1-apb-dma.c
> > > > @@ -0,0 +1,665 @@
> > > > +// SPDX-License-Identifier: GPL-2.0-or-later
> > > > +/*
> > > > + * Driver for Loongson-1 APB DMA Controller
> > > > + *
> > > > + * Copyright (C) 2015-2024 Keguang Zhang <keguang.zhang@gmail.com>
> > > > + */
> > > > +
> > > > +#include <linux/dmapool.h>
> > > > +#include <linux/dma-mapping.h>
> > > > +#include <linux/init.h>
> > > > +#include <linux/interrupt.h>
> > > > +#include <linux/iopoll.h>
> > > > +#include <linux/module.h>
> > > > +#include <linux/of.h>
> > > > +#include <linux/of_dma.h>
> > > > +#include <linux/platform_device.h>
> > > > +#include <linux/slab.h>
> > > > +
> > > > +#include "dmaengine.h"
> > > > +#include "virt-dma.h"
> > > > +
> > > > +/* Loongson-1 DMA Control Register */
> > > > +#define DMA_CTRL                       0x0
> > > > +
> > > > +/* DMA Control Register Bits */
> > > > +#define DMA_STOP                       BIT(4)
> > > > +#define DMA_START                      BIT(3)
> > > > +#define DMA_ASK_VALID                  BIT(2)
> > > > +
> > > > +#define DMA_ADDR_MASK                  GENMASK(31, 6)
> > > > +
> > > > +/* DMA Next Field Bits */
> > > > +#define DMA_NEXT_VALID                 BIT(0)
> > > > +
> > > > +/* DMA Command Field Bits */
> > > > +#define DMA_RAM2DEV                    BIT(12)
> > > > +#define DMA_INT                                BIT(1)
> > > > +#define DMA_INT_MASK                   BIT(0)
> > > > +
> > > > +#define LS1X_DMA_MAX_CHANNELS          3
> > > > +
> > > > +/* Size of allocations for hardware descriptors */
> > > > +#define LS1X_DMA_DESCS_SIZE            PAGE_SIZE
> > > > +#define LS1X_DMA_MAX_DESC              \
> > > > +       (LS1X_DMA_DESCS_SIZE / sizeof(struct ls1x_dma_hwdesc))
> > > > +
> > > > +struct ls1x_dma_hwdesc {
> > > > +       u32 next;               /* next descriptor address */
> > > > +       u32 saddr;              /* memory DMA address */
> > > > +       u32 daddr;              /* device DMA address */
> > > > +       u32 length;
> > > > +       u32 stride;
> > > > +       u32 cycles;
> > > > +       u32 cmd;
> > > > +       u32 stats;
> > > > +};
> > > > +
> > > > +struct ls1x_dma_desc {
> > > > +       struct virt_dma_desc vdesc;
> > > > +       enum dma_transfer_direction dir;
> > > > +       enum dma_transaction_type type;
> > > > +       unsigned int bus_width;
> > > > +
> > > > +       unsigned int nr_descs;  /* number of descriptors */
> > > > +
> > > > +       struct ls1x_dma_hwdesc *hwdesc;
> > > > +       dma_addr_t hwdesc_phys;
> > > > +};
> > > > +
> > > > +struct ls1x_dma_chan {
> > > > +       struct virt_dma_chan vchan;
> > > > +       struct dma_pool *desc_pool;
> > > > +       phys_addr_t src_addr;
> > > > +       phys_addr_t dst_addr;
> > > > +       enum dma_slave_buswidth src_addr_width;
> > > > +       enum dma_slave_buswidth dst_addr_width;
> > > > +
> > > > +       void __iomem *reg_base;
> > > > +       int irq;
> > > > +
> > > > +       struct ls1x_dma_desc *desc;
> > > > +
> > > > +       struct ls1x_dma_hwdesc *curr_hwdesc;
> > > > +       dma_addr_t curr_hwdesc_phys;
> > > > +};
> > > > +
> > > > +struct ls1x_dma {
> > > > +       struct dma_device ddev;
> > > > +       void __iomem *reg_base;
> > > > +
> > > > +       unsigned int nr_chans;
> > > > +       struct ls1x_dma_chan chan[];
> > > > +};
> > > > +
> > > > +#define to_ls1x_dma_chan(dchan)                \
> > > > +       container_of(dchan, struct ls1x_dma_chan, vchan.chan)
> > > > +
> > > > +#define to_ls1x_dma_desc(vd)           \
> > > > +       container_of(vd, struct ls1x_dma_desc, vdesc)
> > > > +
> > > > +/* macros for registers read/write */
> > > > +#define chan_readl(chan, off)          \
> > > > +       readl((chan)->reg_base + (off))
> > > > +
> > > > +#define chan_writel(chan, off, val)    \
> > > > +       writel((val), (chan)->reg_base + (off))
> > > > +
> > > > +static inline struct device *chan2dev(struct dma_chan *chan)
> > > > +{
> > > > +       return &chan->dev->device;
> > > > +}
> > > > +
> > > > +static inline int ls1x_dma_query(struct ls1x_dma_chan *chan,
> > > > +                                dma_addr_t *hwdesc_phys)
> > > > +{
> > > > +       struct dma_chan *dchan = &chan->vchan.chan;
> > > > +       int val, ret;
> > > > +
> > > > +       val = *hwdesc_phys & DMA_ADDR_MASK;
> > > > +       val |= DMA_ASK_VALID;
> > > > +       val |= dchan->chan_id;
> > > > +       chan_writel(chan, DMA_CTRL, val);
> > > > +       ret = readl_poll_timeout_atomic(chan->reg_base + DMA_CTRL, val,
> > > > +                                       !(val & DMA_ASK_VALID), 0, 3000);
> > > > +       if (ret)
> > > > +               dev_err(chan2dev(dchan), "failed to query DMA\n");
> > > > +
> > > > +       return ret;
> > > > +}
> > > > +
> > > > +static inline int ls1x_dma_start(struct ls1x_dma_chan *chan,
> > > > +                                dma_addr_t *hwdesc_phys)
> > > > +{
> > > > +       struct dma_chan *dchan = &chan->vchan.chan;
> > > > +       int val, ret;
> > > > +
> > > > +       dev_dbg(chan2dev(dchan), "cookie=%d, starting hwdesc=%x\n",
> > > > +               dchan->cookie, *hwdesc_phys);
> > > > +
> > > > +       val = *hwdesc_phys & DMA_ADDR_MASK;
> > > > +       val |= DMA_START;
> > > > +       val |= dchan->chan_id;
> > > > +       chan_writel(chan, DMA_CTRL, val);
> > > > +       ret = readl_poll_timeout(chan->reg_base + DMA_CTRL, val,
> > > > +                                !(val & DMA_START), 0, 3000);
> > > > +       if (ret)
> > > > +               dev_err(chan2dev(dchan), "failed to start DMA\n");
> > > > +
> > > > +       return ret;
> > > > +}
> > > > +
> > > > +static inline void ls1x_dma_stop(struct ls1x_dma_chan *chan)
> > > > +{
> > > > +       chan_writel(chan, DMA_CTRL, chan_readl(chan, DMA_CTRL) | DMA_STOP);
> > > > +}
> > > > +
> > > > +static void ls1x_dma_free_chan_resources(struct dma_chan *dchan)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +
> > > > +       dma_free_coherent(chan2dev(dchan), sizeof(struct ls1x_dma_hwdesc),
> > > > +                         chan->curr_hwdesc, chan->curr_hwdesc_phys);
> > > > +       vchan_free_chan_resources(&chan->vchan);
> > > > +       dma_pool_destroy(chan->desc_pool);
> > > > +       chan->desc_pool = NULL;
> > > > +}
> > > > +
> > > > +static int ls1x_dma_alloc_chan_resources(struct dma_chan *dchan)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +
> > > > +       chan->desc_pool = dma_pool_create(dma_chan_name(dchan),
> > > > +                                         chan2dev(dchan),
> > > > +                                         sizeof(struct ls1x_dma_hwdesc),
> > > > +                                         __alignof__(struct ls1x_dma_hwdesc),
> > > > +                                         0);
> > > > +       if (!chan->desc_pool)
> > > > +               return -ENOMEM;
> > > > +
> > > > +       /* allocate memory for querying current HW descriptor */
> > > > +       dma_set_coherent_mask(chan2dev(dchan), DMA_BIT_MASK(32));
> > > > +       chan->curr_hwdesc = dma_alloc_coherent(chan2dev(dchan),
> > > > +                                              sizeof(struct ls1x_dma_hwdesc),
> > > > +                                              &chan->curr_hwdesc_phys,
> > > > +                                              GFP_KERNEL);
> > > > +       if (!chan->curr_hwdesc)
> > > > +               return -ENOMEM;
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +
> > > > +static void ls1x_dma_free_desc(struct virt_dma_desc *vdesc)
> > > > +{
> > > > +       struct ls1x_dma_desc *desc = to_ls1x_dma_desc(vdesc);
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(vdesc->tx.chan);
> > > > +
> > > > +       dma_pool_free(chan->desc_pool, desc->hwdesc, desc->hwdesc_phys);
> > > > +       chan->desc = NULL;
> > > > +       kfree(desc);
> > > > +}
> > > > +
> > > > +static struct ls1x_dma_desc *
> > > > +ls1x_dma_alloc_desc(struct dma_chan *dchan, int sg_len,
> > > > +                   enum dma_transfer_direction direction,
> > > > +                   enum dma_transaction_type type)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +       struct ls1x_dma_desc *desc;
> > > > +
> > > > +       if (sg_len > LS1X_DMA_MAX_DESC) {
> > > > +               dev_err(chan2dev(dchan), "sg_len %u exceeds limit %lu",
> > > > +                       sg_len, LS1X_DMA_MAX_DESC);
> > > > +               return NULL;
> > > > +       }
> > > > +
> > > > +       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
> > > > +       if (!desc)
> > > > +               return NULL;
> > > > +
> > > > +       /* allocate HW descriptors */
> > > > +       desc->hwdesc = dma_pool_zalloc(chan->desc_pool, GFP_NOWAIT,
> > > > +                                      &desc->hwdesc_phys);
> > > > +       if (!desc->hwdesc) {
> > > > +               dev_err(chan2dev(dchan), "failed to alloc HW descriptors\n");
> > > > +               ls1x_dma_free_desc(&desc->vdesc);
> > > > +               return NULL;
> > > > +       }
> > > > +
> > > > +       desc->dir = direction;
> > > > +       desc->type = type;
> > > > +       desc->nr_descs = sg_len;
> > > > +
> > > > +       return desc;
> > > > +}
> > > > +
> > > > +static int ls1x_dma_setup_hwdescs(struct dma_chan *dchan,
> > > > +                                 struct ls1x_dma_desc *desc,
> > > > +                                 struct scatterlist *sgl, unsigned int sg_len)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +       dma_addr_t next_hwdesc_phys = desc->hwdesc_phys;
> > > > +
> > > > +       struct scatterlist *sg;
> > > > +       unsigned int dev_addr, cmd, i;
> > > > +
> > > > +       switch (desc->dir) {
> > > > +       case DMA_MEM_TO_DEV:
> > > > +               dev_addr = chan->dst_addr;
> > > > +               desc->bus_width = chan->dst_addr_width;
> > > > +               cmd = DMA_RAM2DEV | DMA_INT;
> > > > +               break;
> > > > +       case DMA_DEV_TO_MEM:
> > > > +               dev_addr = chan->src_addr;
> > > > +               desc->bus_width = chan->src_addr_width;
> > > > +               cmd = DMA_INT;
> > > > +               break;
> > > > +       default:
> > > > +               dev_err(chan2dev(dchan), "unsupported DMA direction: %s\n",
> > > > +                       dmaengine_get_direction_text(desc->dir));
> > > > +               return -EINVAL;
> > > > +       }
> > > > +
> > > > +       /* setup HW descriptors */
> > > > +       for_each_sg(sgl, sg, sg_len, i) {
> > > > +               dma_addr_t buf_addr = sg_dma_address(sg);
> > > > +               size_t buf_len = sg_dma_len(sg);
> > > > +               struct ls1x_dma_hwdesc *hwdesc = &desc->hwdesc[i];
> > > > +
> > > > +               if (!is_dma_copy_aligned(dchan->device, buf_addr, 0, buf_len)) {
> > > > +                       dev_err(chan2dev(dchan), "buffer is not aligned!\n");
> > > > +                       return -EINVAL;
> > > > +               }
> > > > +
> > > > +               hwdesc->saddr = buf_addr;
> > > > +               hwdesc->daddr = dev_addr;
> > > > +               hwdesc->length = buf_len / desc->bus_width;
> > > > +               hwdesc->stride = 0;
> > > > +               hwdesc->cycles = 1;
> > > > +               hwdesc->cmd = cmd;
> > > > +
> > > > +               if (i) {
> > > > +                       next_hwdesc_phys += sizeof(*hwdesc);
> > > > +                       desc->hwdesc[i - 1].next = next_hwdesc_phys
> > > > +                           | DMA_NEXT_VALID;
> > > > +               }
> > > > +       }
> > > > +
> > > > +       if (desc->type == DMA_CYCLIC)
> > > > +               desc->hwdesc[i - 1].next = desc->hwdesc_phys | DMA_NEXT_VALID;
> > > > +
> > > > +       for_each_sg(sgl, sg, sg_len, i) {
> > > > +               struct ls1x_dma_hwdesc *hwdesc = &desc->hwdesc[i];
> > > > +
> > > > +               print_hex_dump_debug("HW DESC: ", DUMP_PREFIX_OFFSET, 16, 4,
> > > > +                                    hwdesc, sizeof(*hwdesc), false);
> > > > +       }
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +
> > > > +static struct dma_async_tx_descriptor *
> > > > +ls1x_dma_prep_slave_sg(struct dma_chan *dchan,
> > > > +                      struct scatterlist *sgl, unsigned int sg_len,
> > > > +                      enum dma_transfer_direction direction,
> > > > +                      unsigned long flags, void *context)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +       struct ls1x_dma_desc *desc;
> > > > +
> > > > +       dev_dbg(chan2dev(dchan), "sg_len=%u flags=0x%lx dir=%s\n",
> > > > +               sg_len, flags, dmaengine_get_direction_text(direction));
> > > > +
> > > > +       desc = ls1x_dma_alloc_desc(dchan, sg_len, direction, DMA_SLAVE);
> > > > +       if (!desc)
> > > > +               return NULL;
> > > > +
> > > > +       if (ls1x_dma_setup_hwdescs(dchan, desc, sgl, sg_len)) {
> > > > +               ls1x_dma_free_desc(&desc->vdesc);
> > > > +               return NULL;
> > > > +       }
> > > > +
> > > > +       return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
> > > > +}
> > > > +
> > > > +static struct dma_async_tx_descriptor *
> > > > +ls1x_dma_prep_dma_cyclic(struct dma_chan *dchan,
> > > > +                        dma_addr_t buf_addr, size_t buf_len, size_t period_len,
> > > > +                        enum dma_transfer_direction direction,
> > > > +                        unsigned long flags)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +       struct ls1x_dma_desc *desc;
> > > > +       struct scatterlist *sgl;
> > > > +       unsigned int sg_len;
> > > > +       unsigned int i;
> > > > +
> > > > +       dev_dbg(chan2dev(dchan),
> > > > +               "buf_len=%d period_len=%zu flags=0x%lx dir=%s\n", buf_len,
> > > > +               period_len, flags, dmaengine_get_direction_text(direction));
> > > > +
> > > > +       sg_len = buf_len / period_len;
> > > > +       desc = ls1x_dma_alloc_desc(dchan, sg_len, direction, DMA_CYCLIC);
> > > > +       if (!desc)
> > > > +               return NULL;
> > > > +
> > > > +       /* allocate the scatterlist */
> > > > +       sgl = kmalloc_array(sg_len, sizeof(*sgl), GFP_NOWAIT);
> > > > +       if (!sgl)
> > > > +               return NULL;
> > > > +
> > > > +       sg_init_table(sgl, sg_len);
> > > > +       for (i = 0; i < sg_len; ++i) {
> > > > +               sg_set_page(&sgl[i], pfn_to_page(PFN_DOWN(buf_addr)),
> > > > +                           period_len, offset_in_page(buf_addr));
> > > > +               sg_dma_address(&sgl[i]) = buf_addr;
> > > > +               sg_dma_len(&sgl[i]) = period_len;
> > > > +               buf_addr += period_len;
> > > > +       }
> > > > +
> > > > +       if (ls1x_dma_setup_hwdescs(dchan, desc, sgl, sg_len)) {
> > > > +               ls1x_dma_free_desc(&desc->vdesc);
> > > > +               return NULL;
> > > > +       }
> > > > +
> > > > +       kfree(sgl);
> > > > +
> > > > +       return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
> > > > +}
> > > > +
> > > > +static int ls1x_dma_slave_config(struct dma_chan *dchan,
> > > > +                                struct dma_slave_config *config)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +
> > > > +       chan->src_addr = config->src_addr;
> > > > +       chan->src_addr_width = config->src_addr_width;
> > > > +       chan->dst_addr = config->dst_addr;
> > > > +       chan->dst_addr_width = config->dst_addr_width;
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +
> > > > +static int ls1x_dma_pause(struct dma_chan *dchan)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +       unsigned long flags;
> > > > +       int ret;
> > > > +
> > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > +       ret = ls1x_dma_query(chan, &chan->curr_hwdesc_phys);
> > > > +       if (!ret)
> > > > +               ls1x_dma_stop(chan);
> > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > +
> > > > +       return ret;
> > > > +}
> > > > +
> > > > +static int ls1x_dma_resume(struct dma_chan *dchan)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +       unsigned long flags;
> > > > +       int ret;
> > > > +
> > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > +       ret = ls1x_dma_start(chan, &chan->curr_hwdesc_phys);
> > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > +
> > > > +       return ret;
> > > > +}
> > > > +
> > > > +static int ls1x_dma_terminate_all(struct dma_chan *dchan)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +       unsigned long flags;
> > > > +       LIST_HEAD(head);
> > > > +
> > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > +       ls1x_dma_stop(chan);
> > > > +       vchan_get_all_descriptors(&chan->vchan, &head);
> > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > +
> > > > +       vchan_dma_desc_free_list(&chan->vchan, &head);
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +
> > > > +static enum dma_status ls1x_dma_tx_status(struct dma_chan *dchan,
> > > > +                                         dma_cookie_t cookie,
> > > > +                                         struct dma_tx_state *state)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +       struct virt_dma_desc *vdesc;
> > > > +       enum dma_status status;
> > > > +       size_t bytes = 0;
> > > > +       unsigned long flags;
> > > > +
> > > > +       status = dma_cookie_status(dchan, cookie, state);
> > > > +       if (status == DMA_COMPLETE)
> > > > +               return status;
> > > > +
> > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > +       vdesc = vchan_find_desc(&chan->vchan, cookie);
> > > > +       if (chan->desc && cookie == chan->desc->vdesc.tx.cookie) {
> > > > +               struct ls1x_dma_desc *desc = chan->desc;
> > > > +               int i;
> > > > +
> > > > +               if (ls1x_dma_query(chan, &chan->curr_hwdesc_phys))
> > > > +                       return status;
> > > > +
> > > > +               /* locate the current HW descriptor */
> > > > +               for (i = 0; i < desc->nr_descs; i++)
> > > > +                       if (desc->hwdesc[i].next == chan->curr_hwdesc->next)
> > > > +                               break;
> > > > +
> > > > +               /* count the residues */
> > > > +               for (; i < desc->nr_descs; i++)
> > > > +                       bytes += desc->hwdesc[i].length * desc->bus_width;
> > > > +
> > > > +               dma_set_residue(state, bytes);
> > > > +       }
> > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > +
> > > > +       return status;
> > > > +}
> > > > +
> > > > +static void ls1x_dma_issue_pending(struct dma_chan *dchan)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan);
> > > > +       struct virt_dma_desc *vdesc;
> > > > +       unsigned long flags;
> > > > +
> > > > +       spin_lock_irqsave(&chan->vchan.lock, flags);
> > > > +       if (vchan_issue_pending(&chan->vchan) && !chan->desc) {
> > > > +               vdesc = vchan_next_desc(&chan->vchan);
> > > > +               if (!vdesc) {
> > > > +                       chan->desc = NULL;
> > > > +                       return;
> > > > +               }
> > > > +               chan->desc = to_ls1x_dma_desc(vdesc);
> > > > +               ls1x_dma_start(chan, &chan->desc->hwdesc_phys);
> > > > +       }
> > > > +       spin_unlock_irqrestore(&chan->vchan.lock, flags);
> > > > +}
> > > > +
> > > > +static irqreturn_t ls1x_dma_irq_handler(int irq, void *data)
> > > > +{
> > > > +       struct ls1x_dma_chan *chan = data;
> > > > +       struct ls1x_dma_desc *desc = chan->desc;
> > > > +       struct dma_chan *dchan = &chan->vchan.chan;
> > > > +
> > > > +       if (!desc) {
> > > > +               dev_warn(chan2dev(dchan),
> > > > +                        "IRQ %d with no active descriptor on channel %d\n",
> > > > +                        irq, dchan->chan_id);
> > > > +               return IRQ_NONE;
> > > > +       }
> > > > +
> > > > +       dev_dbg(chan2dev(dchan), "DMA IRQ %d on channel %d\n", irq,
> > > > +               dchan->chan_id);
> > > > +
> > > > +       spin_lock(&chan->vchan.lock);
> > > > +
> > > > +       if (desc->type == DMA_CYCLIC) {
> > > > +               vchan_cyclic_callback(&desc->vdesc);
> > > > +       } else {
> > > > +               list_del(&desc->vdesc.node);
> > > > +               vchan_cookie_complete(&desc->vdesc);
> > > > +               chan->desc = NULL;
> > > > +       }
> > > > +
> > > > +       spin_unlock(&chan->vchan.lock);
> > > > +       return IRQ_HANDLED;
> > > > +}
> > > > +
> > > > +static int ls1x_dma_chan_probe(struct platform_device *pdev,
> > > > +                              struct ls1x_dma *dma, int chan_id)
> > > > +{
> > > > +       struct device *dev = &pdev->dev;
> > > > +       struct ls1x_dma_chan *chan = &dma->chan[chan_id];
> > > > +       char pdev_irqname[4];
> > > > +       char *irqname;
> > > > +       int ret;
> > > > +
> > > > +       sprintf(pdev_irqname, "ch%u", chan_id);
> > > > +       chan->irq = platform_get_irq_byname(pdev, pdev_irqname);
> > > > +       if (chan->irq < 0)
> > > > +               return -ENODEV;
> > > > +
> > > > +       irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:%s",
> > > > +                                dev_name(dev), pdev_irqname);
> > > > +       if (!irqname)
> > > > +               return -ENOMEM;
> > > > +
> > > > +       ret = devm_request_irq(dev, chan->irq, ls1x_dma_irq_handler,
> > > > +                              IRQF_SHARED, irqname, chan);
> > > > +       if (ret)
> > > > +               return dev_err_probe(dev, ret,
> > > > +                                    "failed to request IRQ %u!\n", chan->irq);
> > > > +
> > > > +       chan->reg_base = dma->reg_base;
> > > > +       chan->vchan.desc_free = ls1x_dma_free_desc;
> > > > +       vchan_init(&chan->vchan, &dma->ddev);
> > > > +       dev_info(dev, "%s (irq %d) initialized\n", pdev_irqname, chan->irq);
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +
> > > > +static void ls1x_dma_chan_remove(struct ls1x_dma *dma, int chan_id)
> > > > +{
> > > > +       struct device *dev = dma->ddev.dev;
> > > > +       struct ls1x_dma_chan *chan = &dma->chan[chan_id];
> > > > +
> > > > +       devm_free_irq(dev, chan->irq, chan);
> > > > +       list_del(&chan->vchan.chan.device_node);
> > > > +       tasklet_kill(&chan->vchan.task);
> > > > +}
> > > > +
> > > > +static int ls1x_dma_probe(struct platform_device *pdev)
> > > > +{
> > > > +       struct device *dev = &pdev->dev;
> > > > +       struct dma_device *ddev;
> > > > +       struct ls1x_dma *dma;
> > > > +       int nr_chans, ret, i;
> > > > +
> > > > +       nr_chans = platform_irq_count(pdev);
> > > > +       if (nr_chans <= 0)
> > > > +               return nr_chans;
> > > > +       if (nr_chans > LS1X_DMA_MAX_CHANNELS)
> > > > +               return dev_err_probe(dev, -EINVAL,
> > > > +                                    "nr_chans=%d exceeds the maximum\n",
> > > > +                                    nr_chans);
> > > > +
> > > > +       dma = devm_kzalloc(dev, struct_size(dma, chan, nr_chans), GFP_KERNEL);
> > > > +       if (!dma)
> > > > +               return -ENOMEM;
> > > > +
> > > > +       /* initialize DMA device */
> > > > +       dma->reg_base = devm_platform_ioremap_resource(pdev, 0);
> > > > +       if (IS_ERR(dma->reg_base))
> > > > +               return PTR_ERR(dma->reg_base);
> > > > +
> > > > +       ddev = &dma->ddev;
> > > > +       ddev->dev = dev;
> > > > +       ddev->copy_align = DMAENGINE_ALIGN_4_BYTES;
> > > > +       ddev->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> > > > +           BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> > > > +       ddev->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> > > > +           BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> > > > +       ddev->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
> > > > +       ddev->max_sg_burst = LS1X_DMA_MAX_DESC;
> > > > +       ddev->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
> > > > +       ddev->device_alloc_chan_resources = ls1x_dma_alloc_chan_resources;
> > > > +       ddev->device_free_chan_resources = ls1x_dma_free_chan_resources;
> > > > +       ddev->device_prep_slave_sg = ls1x_dma_prep_slave_sg;
> > > > +       ddev->device_prep_dma_cyclic = ls1x_dma_prep_dma_cyclic;
> > > > +       ddev->device_config = ls1x_dma_slave_config;
> > > > +       ddev->device_pause = ls1x_dma_pause;
> > > > +       ddev->device_resume = ls1x_dma_resume;
> > > > +       ddev->device_terminate_all = ls1x_dma_terminate_all;
> > > > +       ddev->device_tx_status = ls1x_dma_tx_status;
> > > > +       ddev->device_issue_pending = ls1x_dma_issue_pending;
> > > > +
> > > > +       dma_cap_set(DMA_SLAVE, ddev->cap_mask);
> > > > +       INIT_LIST_HEAD(&ddev->channels);
> > > > +
> > > > +       /* initialize DMA channels */
> > > > +       for (i = 0; i < nr_chans; i++) {
> > > > +               ret = ls1x_dma_chan_probe(pdev, dma, i);
> > > > +               if (ret)
> > > > +                       return ret;
> > > > +       }
> > > > +       dma->nr_chans = nr_chans;
> > > > +
> > > > +       ret = dmaenginem_async_device_register(ddev);
> > > > +       if (ret) {
> > > > +               dev_err(dev, "failed to register DMA device! %d\n", ret);
> > > > +               return ret;
> > > > +       }
> > > > +
> > > > +       ret =
> > > > +           of_dma_controller_register(dev->of_node, of_dma_xlate_by_chan_id,
> > > > +                                      ddev);
> > > > +       if (ret) {
> > > > +               dev_err(dev, "failed to register DMA controller! %d\n", ret);
> > > > +               return ret;
> > > > +       }
> > > > +
> > > > +       platform_set_drvdata(pdev, dma);
> > > > +       dev_info(dev, "Loongson1 DMA driver registered\n");
> > > > +
> > > > +       return 0;
> > > > +}
> > > > +
> > > > +static void ls1x_dma_remove(struct platform_device *pdev)
> > > > +{
> > > > +       struct ls1x_dma *dma = platform_get_drvdata(pdev);
> > > > +       int i;
> > > > +
> > > > +       of_dma_controller_free(pdev->dev.of_node);
> > > > +
> > > > +       for (i = 0; i < dma->nr_chans; i++)
> > > > +               ls1x_dma_chan_remove(dma, i);
> > > > +}
> > > > +
> > > > +static const struct of_device_id ls1x_dma_match[] = {
> > > > +       { .compatible = "loongson,ls1b-apbdma" },
> > > > +       { .compatible = "loongson,ls1c-apbdma" },
> > > > +       { /* sentinel */ }
> > > > +};
> > > > +MODULE_DEVICE_TABLE(of, ls1x_dma_match);
> > > > +
> > > > +static struct platform_driver ls1x_dma_driver = {
> > > > +       .probe = ls1x_dma_probe,
> > > > +       .remove_new = ls1x_dma_remove,
> > > > +       .driver = {
> > > > +               .name = KBUILD_MODNAME,
> > > > +               .of_match_table = ls1x_dma_match,
> > > > +       },
> > > > +};
> > > > +
> > > > +module_platform_driver(ls1x_dma_driver);
> > > > +
> > > > +MODULE_AUTHOR("Keguang Zhang <keguang.zhang@gmail.com>");
> > > > +MODULE_DESCRIPTION("Loongson-1 APB DMA Controller driver");
> > > > +MODULE_LICENSE("GPL");
> > > >
> > > > --
> > > > 2.40.1
> > > >
> > > >
> >
> >
> >
> > --
> > Best regards,
> >
> > Keguang Zhang
> >



-- 
Best regards,

Keguang Zhang

^ permalink raw reply

* [PATCH v3] dt-bindings: PCI: ti,j721e-pci-host: Add device-id for TI's J784S4 SoC
From: Siddharth Vadapalli @ 2024-04-01 11:09 UTC (permalink / raw)
  To: lpieralisi, kw, robh, bhelgaas, krzysztof.kozlowski+dt, conor+dt,
	kishon
  Cc: linux-pci, devicetree, linux-kernel, linux-arm-kernel, srk,
	s-vadapalli

Add the device-id of 0xb012 for the PCIe controller on the J784S4 SoC as
described in the CTRL_MMR_PCI_DEVICE_ID register's PCI_DEVICE_ID_DEVICE_ID
field. The Register descriptions and the Technical Reference Manual for
J784S4 SoC can be found at: https://www.ti.com/lit/zip/spruj52

Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
Acked-by: Rob Herring <robh@kernel.org>
---

This patch is based on linux-next tagged next-20240328.
v2:
https://patchwork.kernel.org/project/linux-arm-kernel/patch/20240115055236.1840255-1-s-vadapalli@ti.com/
Changes since v2:
- Rebased on next-20240328.

Regards,
Siddharth.

 Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
index b7a534cef24d..0b1f21570ed0 100644
--- a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
+++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
@@ -68,6 +68,7 @@ properties:
       - 0xb00d
       - 0xb00f
       - 0xb010
+      - 0xb012
       - 0xb013
 
   msi-map: true
-- 
2.40.1


^ permalink raw reply related

* Re: [PATCH 2/2] dt-bindings: iio: imu: add icm42688 inside inv_icm42600
From: Conor Dooley @ 2024-04-01 11:04 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: inv.git-commit, robh, krzysztof.kozlowski+dt, conor+dt, lars,
	linux-iio, devicetree, Jean-Baptiste Maneyrol
In-Reply-To: <20240330161012.0b49846a@jic23-huawei>

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

On Sat, Mar 30, 2024 at 04:10:12PM +0000, Jonathan Cameron wrote:
> On Fri, 29 Mar 2024 15:49:26 +0000
> Conor Dooley <conor@kernel.org> wrote:
> 
> > On Fri, Mar 29, 2024 at 03:15:35PM +0000, inv.git-commit@tdk.com wrote:
> > > From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
> > > 
> > > Add bindings for ICM-42688-P chip.
> > > 
> > > Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>  
> > 
> > My initial thought was that you're missing a sign-off, but is
> > "inv.git-commit@tdk.com" some system you have to bypass corporate email
> > garbage?
> 
> Common enough setup, as long as the From: line matches the sign-off, git will
> ignore the email address used to send it when the patch is applied.

Yeah, I know how it works, I do it all the time. Even found, or rather
caused, a b4 bug where it would use the sending email in the eventual
commit rather than the author:
https://lore.kernel.org/tools/20230310192652.ymac3w2lucfdf34p@meerkat.local/

I'm just double checking that there's not a missing signoff. When I've
seen these corp-email-bypass accounts before people set a proper "from"
in git send-email so there's a name in it: "A Dev <inv.git-commit@tdk.com>"

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

^ permalink raw reply

* Re: [PATCH v2] dt-bindings: usb: qcom,pmic-typec: update example to follow connector schema
From: Conor Dooley @ 2024-04-01 10:57 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Dmitry Baryshkov, Bjorn Andersson, Konrad Dybcio,
	Bryan O'Donoghue, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, linux-arm-msm, linux-usb, devicetree, linux-kernel,
	Luca Weiss
In-Reply-To: <2024033109-reporter-blooming-5217@gregkh>

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

On Sun, Mar 31, 2024 at 09:17:20AM +0200, Greg Kroah-Hartman wrote:
> On Sun, Mar 31, 2024 at 12:21:15AM +0200, Dmitry Baryshkov wrote:
> > Update Qualcomm PMIC Type-C examples to follow the USB-C connector
> > schema. The USB-C connector should have three ports (USB HS @0,
> > SSTX/RX @1 and SBU @2 lanes). Reorder ports accordingly and add SBU port
> > connected to the SBU mux (e.g. FSA4480).
> > 
> > Fixes: 00bb478b829e ("dt-bindings: usb: Add Qualcomm PMIC Type-C")
> > Reported-by: Luca Weiss <luca.weiss@fairphone.com>
> > Acked-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> > Update examples to follow usb-c-connector schema wrt. ports definitions.
> > ---
> 
> 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:
> 
> - You have marked a patch with a "Fixes:" tag for a commit that is in an
>   older released kernel, yet you do not have a cc: stable line in the
>   signed-off-by area at all, which means that the patch will not be
>   applied to any older kernel releases.  To properly fix this, please
>   follow the documented rules in the
>   Documentation/process/stable-kernel-rules.rst file for how to resolve
>   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.

I'm not sure that something updating the example like this needs to go
to stable in the first place.

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

^ permalink raw reply

* Re: [PATCH] dt-bindings: PCI: rockchip,rk3399-pcie: add missing maxItems to ep-gpios
From: Conor Dooley @ 2024-04-01 10:46 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Shawn Lin, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Rob Herring, Bjorn Helgaas, Krzysztof Kozlowski, Conor Dooley,
	Heiko Stuebner, linux-pci, linux-rockchip, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20240401100058.15749-1-krzysztof.kozlowski@linaro.org>

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

On Mon, Apr 01, 2024 at 12:00:58PM +0200, Krzysztof Kozlowski wrote:
> Properties with GPIOs should define number of actual GPIOs, so add
> missing maxItems to ep-gpios.  Otherwise multiple GPIOs could be
> provided which is not a true hardware description.
> 
> Fixes: aa222f9311e1 ("dt-bindings: PCI: Convert Rockchip RK3399 PCIe to DT schema")
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Acked-by: Conor Dooley <conor.dooley@microchip.com>

Thanks,
Conor.

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

^ permalink raw reply

* Re: [PATCH v3 3/5] dt-bindings: serial: amlogic,meson-uart: Add compatible string for A4
From: Conor Dooley @ 2024-04-01 10:45 UTC (permalink / raw)
  To: xianwei.zhao
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Neil Armstrong,
	Martin Blumenstingl, Jerome Brunet, Kevin Hilman,
	Greg Kroah-Hartman, Jiri Slaby, devicetree, linux-kernel,
	linux-arm-kernel, linux-amlogic, linux-serial
In-Reply-To: <20240401-basic_dt-v3-3-cb29ae1c16da@amlogic.com>

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

On Mon, Apr 01, 2024 at 06:10:51PM +0800, Xianwei Zhao via B4 Relay wrote:
> From: Xianwei Zhao <xianwei.zhao@amlogic.com>
> 
> Amlogic A4 SoCs uses the same UART controller as S4 SoCs and G12A.
> There is no need for an extra compatible line in the driver, but
> add A4 compatible line for documentation.
> 
> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>

Acked-by: Conor Dooley <conor.dooley@microchip.com>

Thanks,
Conor.

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

^ permalink raw reply


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