Unverified Commit d409f53d authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'clk-imx-6.19' of...

Merge tag 'clk-imx-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux into clk-imx

Pull i.MX clk driver updates from Abel Vesa:

 - Add delay to the PCC enable/disable in i.MX7ULP composite, needed by
   some specific peripherals
 - Simplify the i.MX8MP auxiomix by using devm_auxiliary_device_create()
 - Add the i.MX8ULP SIM LPAV platform specific clock provider

* tag 'clk-imx-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux:
  clk: imx: add driver for imx8ulp's sim lpav
  dt-bindings: clock: document 8ULP's SIM LPAV
  clk: imx: imx8mp-audiomix: use devm_auxiliary_device_create() to simple code
  clk: imx: Add some delay before deassert the reset
parents 3a866087 fdc1dc7d
Loading
Loading
Loading
Loading
+72 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/fsl,imx8ulp-sim-lpav.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: NXP i.MX8ULP LPAV System Integration Module (SIM)

maintainers:
  - Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>

description:
  The i.MX8ULP LPAV subsystem contains a block control module known as
  SIM LPAV, which offers functionalities such as clock gating or reset
  line assertion/de-assertion.

properties:
  compatible:
    const: fsl,imx8ulp-sim-lpav

  reg:
    maxItems: 1

  clocks:
    maxItems: 3

  clock-names:
    items:
      - const: bus
      - const: core
      - const: plat

  '#clock-cells':
    const: 1

  '#reset-cells':
    const: 1

  mux-controller:
    $ref: /schemas/mux/reg-mux.yaml#

required:
  - compatible
  - reg
  - clocks
  - clock-names
  - '#clock-cells'
  - '#reset-cells'
  - mux-controller

additionalProperties: false

examples:
  - |
    #include <dt-bindings/clock/imx8ulp-clock.h>

    clock-controller@2da50000 {
        compatible = "fsl,imx8ulp-sim-lpav";
        reg = <0x2da50000 0x10000>;
        clocks = <&cgc2 IMX8ULP_CLK_LPAV_BUS_DIV>,
                 <&cgc2 IMX8ULP_CLK_HIFI_DIVCORE>,
                 <&cgc2 IMX8ULP_CLK_HIFI_DIVPLAT>;
        clock-names = "bus", "core", "plat";
        #clock-cells = <1>;
        #reset-cells = <1>;

        mux-controller {
            compatible = "reg-mux";
            #mux-control-cells = <1>;
            mux-reg-masks = <0x8 0x00000200>;
        };
    };
+1 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ config CLK_IMX8ULP
	tristate "IMX8ULP CCM Clock Driver"
	depends on ARCH_MXC || COMPILE_TEST
	select MXC_CLK
	select AUXILIARY_BUS
	help
	    Build the driver for i.MX8ULP CCM Clock Driver

+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o
clk-imx-acm-$(CONFIG_CLK_IMX8QXP) = clk-imx8-acm.o

obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp.o
obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp-sim-lpav.o

obj-$(CONFIG_CLK_IMX1)   += clk-imx1.o
obj-$(CONFIG_CLK_IMX25)  += clk-imx25.o
+13 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@

#include <linux/bits.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/slab.h>
@@ -36,6 +37,9 @@ static int pcc_gate_enable(struct clk_hw *hw)
	if (ret)
		return ret;

	/* Make sure the IP's clock is ready before release reset */
	udelay(1);

	spin_lock_irqsave(gate->lock, flags);
	/*
	 * release the sw reset for peripherals associated with
@@ -47,6 +51,15 @@ static int pcc_gate_enable(struct clk_hw *hw)

	spin_unlock_irqrestore(gate->lock, flags);

	/*
	 * Read back the register to make sure the previous write has been
	 * done in the target HW register. For IP like GPU, after deassert
	 * the reset, need to wait for a while to make sure the sync reset
	 * is done
	 */
	readl(gate->reg);
	udelay(1);

	return 0;
}

+4 −35
Original line number Diff line number Diff line
@@ -230,50 +230,19 @@ struct clk_imx8mp_audiomix_priv {

#if IS_ENABLED(CONFIG_RESET_CONTROLLER)

static void clk_imx8mp_audiomix_reset_unregister_adev(void *_adev)
{
	struct auxiliary_device *adev = _adev;

	auxiliary_device_delete(adev);
	auxiliary_device_uninit(adev);
}

static void clk_imx8mp_audiomix_reset_adev_release(struct device *dev)
{
	struct auxiliary_device *adev = to_auxiliary_dev(dev);

	kfree(adev);
}

static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev,
							 struct clk_imx8mp_audiomix_priv *priv)
{
	struct auxiliary_device *adev __free(kfree) = NULL;
	int ret;
	struct auxiliary_device *adev;

	if (!of_property_present(dev->of_node, "#reset-cells"))
		return 0;

	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
	adev = devm_auxiliary_device_create(dev, "reset", NULL);
	if (!adev)
		return -ENOMEM;
		return -ENODEV;

	adev->name = "reset";
	adev->dev.parent = dev;
	adev->dev.release = clk_imx8mp_audiomix_reset_adev_release;

	ret = auxiliary_device_init(adev);
	if (ret)
		return ret;

	ret = auxiliary_device_add(adev);
	if (ret) {
		auxiliary_device_uninit(adev);
		return ret;
	}

	return devm_add_action_or_reset(dev, clk_imx8mp_audiomix_reset_unregister_adev,
					no_free_ptr(adev));
	return 0;
}

#else /* !CONFIG_RESET_CONTROLLER */
Loading