Commit 702a582b authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge branches 'clk-doc', 'clk-amlogic', 'clk-mediatek', 'clk-twl' and 'clk-imx' into clk-next

 - Add clock driver for TWL6032

* clk-doc:
  clk: linux/clk-provider.h: fix kernel-doc warnings and typos

* clk-amlogic:
  clk: meson: S4: select CONFIG_COMMON_CLK_MESON_CLKC_UTILS
  clk: meson: S4: add support for Amlogic S4 SoC peripheral clock controller
  clk: meson: S4: add support for Amlogic S4 SoC PLL clock driver
  dt-bindings: clock: document Amlogic S4 SoC peripherals clock controller
  dt-bindings: clock: document Amlogic S4 SoC PLL clock controller

* clk-mediatek:
  clk: mediatek: fix double free in mtk_clk_register_pllfh()
  clk: mediatek: clk-mt2701: Add check for mtk_alloc_clk_data
  clk: mediatek: clk-mt7629: Add check for mtk_alloc_clk_data
  clk: mediatek: clk-mt7629-eth: Add check for mtk_alloc_clk_data
  clk: mediatek: clk-mt6797: Add check for mtk_alloc_clk_data
  clk: mediatek: clk-mt6779: Add check for mtk_alloc_clk_data
  clk: mediatek: clk-mt6765: Add check for mtk_alloc_clk_data

* clk-twl:
  clk: twl: add clock driver for TWL6032

* clk-imx:
  clk: imx: imx8qm/qxp: add more resources to whitelist
  clk: imx: scu: ignore clks not owned by Cortex-A partition
  clk: imx8: remove MLB support
  clk: imx: imx8qm-rsrc: drop VPU_UART/VPUCORE
  clk: imx: imx8qxp: correct the enet clocks for i.MX8DXL
  clk: imx: imx8qxp: Fix elcdif_pll clock
  clk: imx: imx8dxl-rsrc: keep sorted in the ascending order
  clk: imx: imx6sx: Allow a different LCDIF1 clock parent
  clk: imx: imx8mq: correct error handling path
  clk: imx8mp: Remove non-existent IMX8MP_CLK_AUDIOMIX_PDM_ROOT
  clk: imx: imx8: Simplify clk_imx_acm_detach_pm_domains()
  clk: imx: imx8: Add a message in case of devm_clk_hw_register_mux_parent_data_table() error
  clk: imx: imx8: Fix an error handling path in imx8_acm_clk_probe()
  clk: imx: imx8: Fix an error handling path if devm_clk_hw_register_mux_parent_data_table() fails
  clk: imx: imx8: Fix an error handling path in clk_imx_acm_attach_pm_domains()
  clk: imx: Select MXC_CLK for CLK_IMX8QXP
Loading
Loading
Loading
Loading
+96 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/amlogic,s4-peripherals-clkc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Amlogic S4 Peripherals Clock Controller

maintainers:
  - Yu Tu <yu.tu@amlogic.com>

properties:
  compatible:
    const: amlogic,s4-peripherals-clkc

  reg:
    maxItems: 1

  clocks:
    minItems: 14
    items:
      - description: input fixed pll div2
      - description: input fixed pll div2p5
      - description: input fixed pll div3
      - description: input fixed pll div4
      - description: input fixed pll div5
      - description: input fixed pll div7
      - description: input hifi pll
      - description: input gp0 pll
      - description: input mpll0
      - description: input mpll1
      - description: input mpll2
      - description: input mpll3
      - description: input hdmi pll
      - description: input oscillator (usually at 24MHz)
      - description: input external 32kHz reference (optional)

  clock-names:
    minItems: 14
    items:
      - const: fclk_div2
      - const: fclk_div2p5
      - const: fclk_div3
      - const: fclk_div4
      - const: fclk_div5
      - const: fclk_div7
      - const: hifi_pll
      - const: gp0_pll
      - const: mpll0
      - const: mpll1
      - const: mpll2
      - const: mpll3
      - const: hdmi_pll
      - const: xtal
      - const: ext_32k

  "#clock-cells":
    const: 1

required:
  - compatible
  - reg
  - clocks
  - clock-names
  - "#clock-cells"

additionalProperties: false

examples:
  - |
    #include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h>

    clkc_periphs: clock-controller@fe000000 {
      compatible = "amlogic,s4-peripherals-clkc";
      reg = <0xfe000000 0x49c>;
      clocks = <&clkc_pll 3>,
              <&clkc_pll 13>,
              <&clkc_pll 5>,
              <&clkc_pll 7>,
              <&clkc_pll 9>,
              <&clkc_pll 11>,
              <&clkc_pll 17>,
              <&clkc_pll 15>,
              <&clkc_pll 25>,
              <&clkc_pll 27>,
              <&clkc_pll 29>,
              <&clkc_pll 31>,
              <&clkc_pll 20>,
              <&xtal>;
      clock-names = "fclk_div2", "fclk_div2p5", "fclk_div3", "fclk_div4",
                    "fclk_div5", "fclk_div7", "hifi_pll", "gp0_pll",
                    "mpll0", "mpll1", "mpll2", "mpll3", "hdmi_pll", "xtal";
      #clock-cells = <1>;
    };
...
+49 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/amlogic,s4-pll-clkc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Amlogic S4 PLL Clock Controller

maintainers:
  - Yu Tu <yu.tu@amlogic.com>

properties:
  compatible:
    const: amlogic,s4-pll-clkc

  reg:
    maxItems: 1

  clocks:
    maxItems: 1

  clock-names:
    items:
      - const: xtal

  "#clock-cells":
    const: 1

required:
  - compatible
  - reg
  - clocks
  - clock-names
  - "#clock-cells"

additionalProperties: false

examples:
  - |
    clkc_pll: clock-controller@fe008000 {
      compatible = "amlogic,s4-pll-clkc";
      reg = <0xfe008000 0x1e8>;
      clocks = <&xtal>;
      clock-names = "xtal";
      #clock-cells = <1>;
    };

...
+9 −0
Original line number Diff line number Diff line
@@ -277,6 +277,15 @@ config COMMON_CLK_S2MPS11
	  clock. These multi-function devices have two (S2MPS14) or three
	  (S2MPS11, S5M8767) fixed-rate oscillators, clocked at 32KHz each.

config CLK_TWL
	tristate "Clock driver for the TWL PMIC family"
	depends on TWL4030_CORE
	help
	  Enable support for controlling the clock resources on TWL family
	  PMICs. These devices have some 32K clock outputs which can be
	  controlled by software. For now, only the TWL6032 clocks are
	  supported.

config CLK_TWL6040
	tristate "External McPDM functional clock from twl6040"
	depends on TWL6040_CORE
+1 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
obj-$(CONFIG_COMMON_CLK_STM32MP157)	+= clk-stm32mp1.o
obj-$(CONFIG_COMMON_CLK_TPS68470)      += clk-tps68470.o
obj-$(CONFIG_CLK_TWL6040)		+= clk-twl6040.o
obj-$(CONFIG_CLK_TWL)			+= clk-twl.o
obj-$(CONFIG_ARCH_VT8500)		+= clk-vt8500.o
obj-$(CONFIG_COMMON_CLK_RS9_PCIE)	+= clk-renesas-pcie.o
obj-$(CONFIG_COMMON_CLK_SI521XX)	+= clk-si521xx.o

drivers/clk/clk-twl.c

0 → 100644
+197 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Clock driver for twl device.
 *
 * inspired by the driver for the Palmas device
 */

#include <linux/clk-provider.h>
#include <linux/mfd/twl.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#define VREG_STATE              2
#define TWL6030_CFG_STATE_OFF   0x00
#define TWL6030_CFG_STATE_ON    0x01
#define TWL6030_CFG_STATE_MASK  0x03

struct twl_clock_info {
	struct device *dev;
	u8 base;
	struct clk_hw hw;
};

static inline int
twlclk_read(struct twl_clock_info *info, unsigned int slave_subgp,
	    unsigned int offset)
{
	u8 value;
	int status;

	status = twl_i2c_read_u8(slave_subgp, &value,
				 info->base + offset);
	return (status < 0) ? status : value;
}

static inline int
twlclk_write(struct twl_clock_info *info, unsigned int slave_subgp,
	     unsigned int offset, u8 value)
{
	return twl_i2c_write_u8(slave_subgp, value,
				info->base + offset);
}

static inline struct twl_clock_info *to_twl_clks_info(struct clk_hw *hw)
{
	return container_of(hw, struct twl_clock_info, hw);
}

static unsigned long twl_clks_recalc_rate(struct clk_hw *hw,
					  unsigned long parent_rate)
{
	return 32768;
}

static int twl6032_clks_prepare(struct clk_hw *hw)
{
	struct twl_clock_info *cinfo = to_twl_clks_info(hw);
	int ret;

	ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
			   TWL6030_CFG_STATE_ON);
	if (ret < 0)
		dev_err(cinfo->dev, "clk prepare failed\n");

	return ret;
}

static void twl6032_clks_unprepare(struct clk_hw *hw)
{
	struct twl_clock_info *cinfo = to_twl_clks_info(hw);
	int ret;

	ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
			   TWL6030_CFG_STATE_OFF);
	if (ret < 0)
		dev_err(cinfo->dev, "clk unprepare failed\n");
}

static int twl6032_clks_is_prepared(struct clk_hw *hw)
{
	struct twl_clock_info *cinfo = to_twl_clks_info(hw);
	int val;

	val = twlclk_read(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE);
	if (val < 0) {
		dev_err(cinfo->dev, "clk read failed\n");
		return val;
	}

	val &= TWL6030_CFG_STATE_MASK;

	return val == TWL6030_CFG_STATE_ON;
}

static const struct clk_ops twl6032_clks_ops = {
	.prepare	= twl6032_clks_prepare,
	.unprepare	= twl6032_clks_unprepare,
	.is_prepared	= twl6032_clks_is_prepared,
	.recalc_rate	= twl_clks_recalc_rate,
};

struct twl_clks_data {
	struct clk_init_data init;
	u8 base;
};

static const struct twl_clks_data twl6032_clks[] = {
	{
		.init = {
			.name = "clk32kg",
			.ops = &twl6032_clks_ops,
			.flags = CLK_IGNORE_UNUSED,
		},
		.base = 0x8C,
	},
	{
		.init = {
			.name = "clk32kaudio",
			.ops = &twl6032_clks_ops,
			.flags = CLK_IGNORE_UNUSED,
		},
		.base = 0x8F,
	},
	{
		/* sentinel */
	}
};

static int twl_clks_probe(struct platform_device *pdev)
{
	struct clk_hw_onecell_data *clk_data;
	const struct twl_clks_data *hw_data;

	struct twl_clock_info *cinfo;
	int ret;
	int i;
	int count;

	hw_data = twl6032_clks;
	for (count = 0; hw_data[count].init.name; count++)
		;

	clk_data = devm_kzalloc(&pdev->dev,
				struct_size(clk_data, hws, count),
				GFP_KERNEL);
	if (!clk_data)
		return -ENOMEM;

	clk_data->num = count;
	cinfo = devm_kcalloc(&pdev->dev, count, sizeof(*cinfo), GFP_KERNEL);
	if (!cinfo)
		return -ENOMEM;

	for (i = 0; i < count; i++) {
		cinfo[i].base = hw_data[i].base;
		cinfo[i].dev = &pdev->dev;
		cinfo[i].hw.init = &hw_data[i].init;
		ret = devm_clk_hw_register(&pdev->dev, &cinfo[i].hw);
		if (ret) {
			return dev_err_probe(&pdev->dev, ret,
					     "Fail to register clock %s\n",
					     hw_data[i].init.name);
		}
		clk_data->hws[i] = &cinfo[i].hw;
	}

	ret = devm_of_clk_add_hw_provider(&pdev->dev,
					  of_clk_hw_onecell_get, clk_data);
	if (ret < 0)
		return dev_err_probe(&pdev->dev, ret,
				     "Fail to add clock driver\n");

	return 0;
}

static const struct platform_device_id twl_clks_id[] = {
	{
		.name = "twl6032-clk",
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(platform, twl_clks_id);

static struct platform_driver twl_clks_driver = {
	.driver = {
		.name = "twl-clk",
	},
	.probe = twl_clks_probe,
	.id_table = twl_clks_id,
};

module_platform_driver(twl_clks_driver);

MODULE_DESCRIPTION("Clock driver for TWL Series Devices");
MODULE_LICENSE("GPL");
Loading