Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b183c688 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge branches 'clk-imx6-video-parent', 'clk-qcom-sdm845-criticals',...

Merge branches 'clk-imx6-video-parent', 'clk-qcom-sdm845-criticals', 'clk-renesas', 'clk-stratix10-fixes' and 'clk-atmel-i2s' into clk-next

* clk-imx6-video-parent:
  :  - Fix i.MX6QDL video clk parent
  clk: imx6: fix video_27m parent for IMX6QDL_CLK_CKO1_SEL

* clk-qcom-sdm845-criticals:
  :  - critical clk markings for qcom SDM845
  clk: qcom: Enable clocks which needs to be always on for SDM845

* clk-renesas:
  clk: renesas: Renesas R9A06G032 clock driver
  dt-bindings: clock: renesas,r9a06g032-sysctrl: documentation
  dt-bindings: clock: Add the r9a06g032-sysctrl.h file
  clk: renesas: r8a7795: Add CCREE clock
  clk: renesas: r8a7795: Add CR clock

* clk-stratix10-fixes:
  :  - Fix Stratix10 mpu_free_clk and sdmmc_free_clk parents
  clk: socfpga: stratix10: fix the sdmmc_free_clk mux
  clk: socfpga: stratix10: fix the parents of mpu_free_clk

* clk-atmel-i2s:
  :  - Atmel at91 I2S audio clk support
  clk: at91: add I2S clock mux driver
  dt-bindings: clk: at91: add an I2S mux clock
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -91,6 +91,9 @@ Required properties:
		at91 audio pll output on AUDIOPLLCLK that feeds the PMC
		and can be used by peripheral clock or generic clock

	"atmel,sama5d2-clk-i2s-mux" (under pmc node):
		at91 I2S clock source selection

Required properties for SCKC node:
- reg : defines the IO memory reserved for the SCKC.
- #size-cells : shall be 0 (reg is used to encode clk id).
@@ -507,3 +510,35 @@ For example:
			atmel,clk-output-range = <0 83000000>;
		};
	};

Required properties for I2S mux clocks:
- #size-cells : shall be 0 (reg is used to encode I2S bus id).
- #address-cells : shall be 1 (reg is used to encode I2S bus id).
- name: device tree node describing a specific mux clock.
	* #clock-cells : from common clock binding; shall be set to 0.
	* clocks : shall be the mux clock parent phandles; shall be 2 phandles:
	  peripheral and generated clock; the first phandle shall belong to the
	  peripheral clock and the second one shall belong to the generated
	  clock; "clock-indices" property can be user to specify
	  the correct order.
	* reg: I2S bus id of the corresponding mux clock.
	  e.g. reg = <0>; for i2s0, reg = <1>; for i2s1

For example:
	i2s_clkmux {
		compatible = "atmel,sama5d2-clk-i2s-mux";
		#address-cells = <1>;
		#size-cells = <0>;

		i2s0muxck: i2s0_muxclk {
			clocks = <&i2s0_clk>, <&i2s0_gclk>;
			#clock-cells = <0>;
			reg = <0>;
		};

		i2s1muxck: i2s1_muxclk {
			clocks = <&i2s1_clk>, <&i2s1_gclk>;
			#clock-cells = <0>;
			reg = <1>;
		};
	};
+43 −0
Original line number Diff line number Diff line
* Renesas R9A06G032 SYSCTRL

Required Properties:

  - compatible: Must be:
    - "renesas,r9a06g032-sysctrl"
  - reg: Base address and length of the SYSCTRL IO block.
  - #clock-cells: Must be 1
  - clocks: References to the parent clocks:
	- external 40mhz crystal.
	- external (optional) 32.768khz
	- external (optional) jtag input
	- external (optional) RGMII_REFCLK
  - clock-names: Must be:
        clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext";

Examples
--------

  - SYSCTRL node:

	sysctrl: system-controller@4000c000 {
		compatible = "renesas,r9a06g032-sysctrl";
		reg = <0x4000c000 0x1000>;
		#clock-cells = <1>;

		clocks = <&ext_mclk>, <&ext_rtc_clk>,
				<&ext_jtag_clk>, <&ext_rgmii_ref>;
		clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext";
	};

  - Other nodes can use the clocks provided by SYSCTRL as in:

	#include <dt-bindings/clock/r9a06g032-sysctrl.h>
	uart0: serial@40060000 {
		compatible = "snps,dw-apb-uart";
		reg = <0x40060000 0x400>;
		interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
		reg-shift = <2>;
		reg-io-width = <4>;
		clocks = <&sysctrl R9A06G032_CLK_UART0>;
		clock-names = "baudclk";
	};
+4 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ config SOC_SAMA5D2
	select HAVE_AT91_H32MX
	select HAVE_AT91_GENERATED_CLK
	select HAVE_AT91_AUDIO_PLL
	select HAVE_AT91_I2S_MUX_CLK
	select PINCTRL_AT91PIO4
	help
	  Select this if ou are using one of Microchip's SAMA5D2 family SoC.
@@ -129,6 +130,9 @@ config HAVE_AT91_GENERATED_CLK
config HAVE_AT91_AUDIO_PLL
	bool

config HAVE_AT91_I2S_MUX_CLK
	bool

config SOC_SAM_V4_V5
	bool

+1 −0
Original line number Diff line number Diff line
@@ -13,3 +13,4 @@ obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o
obj-$(CONFIG_HAVE_AT91_SMD)		+= clk-smd.o
obj-$(CONFIG_HAVE_AT91_H32MX)		+= clk-h32mx.o
obj-$(CONFIG_HAVE_AT91_GENERATED_CLK)	+= clk-generated.o
obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK)	+= clk-i2s-mux.o
+116 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 *  Copyright (C) 2018 Microchip Technology Inc,
 *                     Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
 *
 *
 */

#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include <soc/at91/atmel-sfr.h>

#define	I2S_BUS_NR	2

struct clk_i2s_mux {
	struct clk_hw hw;
	struct regmap *regmap;
	u8 bus_id;
};

#define to_clk_i2s_mux(hw) container_of(hw, struct clk_i2s_mux, hw)

static u8 clk_i2s_mux_get_parent(struct clk_hw *hw)
{
	struct clk_i2s_mux *mux = to_clk_i2s_mux(hw);
	u32 val;

	regmap_read(mux->regmap, AT91_SFR_I2SCLKSEL, &val);

	return (val & BIT(mux->bus_id)) >> mux->bus_id;
}

static int clk_i2s_mux_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_i2s_mux *mux = to_clk_i2s_mux(hw);

	return regmap_update_bits(mux->regmap, AT91_SFR_I2SCLKSEL,
				  BIT(mux->bus_id), index << mux->bus_id);
}

static const struct clk_ops clk_i2s_mux_ops = {
	.get_parent = clk_i2s_mux_get_parent,
	.set_parent = clk_i2s_mux_set_parent,
	.determine_rate = __clk_mux_determine_rate,
};

static struct clk_hw * __init
at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
			  const char * const *parent_names,
			  unsigned int num_parents, u8 bus_id)
{
	struct clk_init_data init = {};
	struct clk_i2s_mux *i2s_ck;
	int ret;

	i2s_ck = kzalloc(sizeof(*i2s_ck), GFP_KERNEL);
	if (!i2s_ck)
		return ERR_PTR(-ENOMEM);

	init.name = name;
	init.ops = &clk_i2s_mux_ops;
	init.parent_names = parent_names;
	init.num_parents = num_parents;

	i2s_ck->hw.init = &init;
	i2s_ck->bus_id = bus_id;
	i2s_ck->regmap = regmap;

	ret = clk_hw_register(NULL, &i2s_ck->hw);
	if (ret) {
		kfree(i2s_ck);
		return ERR_PTR(ret);
	}

	return &i2s_ck->hw;
}

static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
{
	struct regmap *regmap_sfr;
	u8 bus_id;
	const char *parent_names[2];
	struct device_node *i2s_mux_np;
	struct clk_hw *hw;
	int ret;

	regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
	if (IS_ERR(regmap_sfr))
		return;

	for_each_child_of_node(np, i2s_mux_np) {
		if (of_property_read_u8(i2s_mux_np, "reg", &bus_id))
			continue;

		if (bus_id > I2S_BUS_NR)
			continue;

		ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2);
		if (ret != 2)
			continue;

		hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name,
					       parent_names, 2, bus_id);
		if (IS_ERR(hw))
			continue;

		of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw);
	}
}

CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux",
	       of_sama5d2_clk_i2s_mux_setup);
Loading