Commit 699eda28 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge branches 'clk-tegra', 'clk-imx', 'clk-sifive', 'clk-mediatek' and 'clk-summary' into clk-next

 - Support for SiFive FU740 PRCI
 - Add hardware enable information to clk_summary debugfs

* clk-tegra:
  clk: tegra: Fix duplicated SE clock entry
  clk: tegra: bpmp: Clamp clock rates on requests
  clk: tegra: Do not return 0 on failure

* clk-imx: (24 commits)
  clk: imx: scu: remove the calling of device_is_bound
  clk: imx: scu: Make pd_np with static keyword
  clk: imx8mq: drop of_match_ptr from of_device_id table
  clk: imx8mp: drop of_match_ptr from of_device_id table
  clk: imx8mn: drop of_match_ptr from of_device_id table
  clk: imx8mm: drop of_match_ptr from of_device_id table
  clk: imx: gate2: Remove unused variable ret
  clk: imx: gate2: Add locking in is_enabled op
  clk: imx: gate2: Add cgr_mask for more flexible number of control bits
  clk: imx: gate2: Check if clock is enabled against cgr_val
  clk: imx: gate2: Keep the register writing in on place
  clk: imx: gate2: Remove the IMX_CLK_GATE2_SINGLE_BIT special case
  clk: imx: scu: fix build break when compiled as modules
  clk: imx: remove redundant assignment to pointer np
  clk: imx: remove unneeded semicolon
  clk: imx: lpcg: add suspend/resume support
  clk: imx: clk-imx8qxp-lpcg: add runtime pm support
  clk: imx: lpcg: allow lpcg clk to take device pointer
  clk: imx: imx8qxp-lpcg: add parsing clocks from device tree
  clk: imx: scu: add suspend/resume support
  ...

* clk-sifive:
  clk: sifive: Add clock enable and disable ops
  clk: sifive: Fix the wrong bit field shift
  clk: sifive: Add a driver for the SiFive FU740 PRCI IP block
  clk: sifive: Use common name for prci configuration
  clk: sifive: Extract prci core to common base
  dt-bindings: fu740: prci: add YAML documentation for the FU740 PRCI

* clk-mediatek:
  clk: mediatek: Make mtk_clk_register_mux() a static function

* clk-summary:
  clk: Add hardware-enable column to clk summary
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2020 SiFive, Inc.
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/sifive/fu740-prci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: SiFive FU740 Power Reset Clock Interrupt Controller (PRCI)

maintainers:
  - Zong Li <zong.li@sifive.com>
  - Paul Walmsley  <paul.walmsley@sifive.com>

description:
  On the FU740 family of SoCs, most system-wide clock and reset integration
  is via the PRCI IP block.
  The clock consumer should specify the desired clock via the clock ID
  macros defined in include/dt-bindings/clock/sifive-fu740-prci.h.
  These macros begin with PRCI_CLK_.

  The hfclk and rtcclk nodes are required, and represent physical
  crystals or resonators located on the PCB.  These nodes should be present
  underneath /, rather than /soc.

properties:
  compatible:
    const: sifive,fu740-c000-prci

  reg:
    maxItems: 1

  clocks:
    items:
      - description: high frequency clock.
      - description: RTL clock.

  clock-names:
    items:
      - const: hfclk
      - const: rtcclk

  "#clock-cells":
    const: 1

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

additionalProperties: false

examples:
  - |
    prci: clock-controller@10000000 {
      compatible = "sifive,fu740-c000-prci";
      reg = <0x10000000 0x1000>;
      clocks = <&hfclk>, <&rtcclk>;
      #clock-cells = <1>;
    };
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ config SOC_SIFIVE
	select SERIAL_SIFIVE if TTY
	select SERIAL_SIFIVE_CONSOLE if TTY
	select CLK_SIFIVE
	select CLK_SIFIVE_FU540_PRCI
	select CLK_SIFIVE_PRCI
	select SIFIVE_PLIC
	help
	  This enables support for SiFive SoC platform hardware.
+11 −4
Original line number Diff line number Diff line
@@ -2931,7 +2931,14 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
	else
		seq_puts(s, "-----");

	seq_printf(s, " %6d\n", clk_core_get_scaled_duty_cycle(c, 100000));
	seq_printf(s, " %6d", clk_core_get_scaled_duty_cycle(c, 100000));

	if (c->ops->is_enabled)
		seq_printf(s, " %9c\n", clk_core_is_enabled(c) ? 'Y' : 'N');
	else if (!c->ops->enable)
		seq_printf(s, " %9c\n", 'Y');
	else
		seq_printf(s, " %9c\n", '?');
}

static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
@@ -2950,9 +2957,9 @@ static int clk_summary_show(struct seq_file *s, void *data)
	struct clk_core *c;
	struct hlist_head **lists = (struct hlist_head **)s->private;

	seq_puts(s, "                                 enable  prepare  protect                                duty\n");
	seq_puts(s, "   clock                          count    count    count        rate   accuracy phase  cycle\n");
	seq_puts(s, "---------------------------------------------------------------------------------------------\n");
	seq_puts(s, "                                 enable  prepare  protect                                duty  hardware\n");
	seq_puts(s, "   clock                          count    count    count        rate   accuracy phase  cycle    enable\n");
	seq_puts(s, "-------------------------------------------------------------------------------------------------------\n");

	clk_prepare_lock();

+32 −36
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ struct clk_gate2 {
	void __iomem	*reg;
	u8		bit_idx;
	u8		cgr_val;
	u8		cgr_mask;
	u8		flags;
	spinlock_t	*lock;
	unsigned int	*share_count;
@@ -37,37 +38,38 @@ struct clk_gate2 {

#define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw)

static int clk_gate2_enable(struct clk_hw *hw)
static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	u32 reg;

	reg = readl(gate->reg);
	reg &= ~(gate->cgr_mask << gate->bit_idx);
	if (enable)
		reg |= (gate->cgr_val & gate->cgr_mask) << gate->bit_idx;
	writel(reg, gate->reg);
}

static int clk_gate2_enable(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(gate->lock, flags);

	if (gate->share_count && (*gate->share_count)++ > 0)
		goto out;

	if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
		ret = clk_gate_ops.enable(hw);
	} else {
		reg = readl(gate->reg);
		reg &= ~(3 << gate->bit_idx);
		reg |= gate->cgr_val << gate->bit_idx;
		writel(reg, gate->reg);
	}

	clk_gate2_do_shared_clks(hw, true);
out:
	spin_unlock_irqrestore(gate->lock, flags);

	return ret;
	return 0;
}

static void clk_gate2_disable(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	u32 reg;
	unsigned long flags;

	spin_lock_irqsave(gate->lock, flags);
@@ -79,23 +81,17 @@ static void clk_gate2_disable(struct clk_hw *hw)
			goto out;
	}

	if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
		clk_gate_ops.disable(hw);
	} else {
		reg = readl(gate->reg);
		reg &= ~(3 << gate->bit_idx);
		writel(reg, gate->reg);
	}

	clk_gate2_do_shared_clks(hw, false);
out:
	spin_unlock_irqrestore(gate->lock, flags);
}

static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx)
static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx,
					u8 cgr_val, u8 cgr_mask)
{
	u32 val = readl(reg);

	if (((val >> bit_idx) & 1) == 1)
	if (((val >> bit_idx) & cgr_mask) == cgr_val)
		return 1;

	return 0;
@@ -104,29 +100,28 @@ static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx)
static int clk_gate2_is_enabled(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(gate->lock, flags);

	if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
		return clk_gate_ops.is_enabled(hw);
	ret = clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx,
					gate->cgr_val, gate->cgr_mask);

	return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
	spin_unlock_irqrestore(gate->lock, flags);

	return ret;
}

static void clk_gate2_disable_unused(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	unsigned long flags;
	u32 reg;

	if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
		return;

	spin_lock_irqsave(gate->lock, flags);

	if (!gate->share_count || *gate->share_count == 0) {
		reg = readl(gate->reg);
		reg &= ~(3 << gate->bit_idx);
		writel(reg, gate->reg);
	}
	if (!gate->share_count || *gate->share_count == 0)
		clk_gate2_do_shared_clks(hw, false);

	spin_unlock_irqrestore(gate->lock, flags);
}
@@ -140,7 +135,7 @@ static const struct clk_ops clk_gate2_ops = {

struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
		const char *parent_name, unsigned long flags,
		void __iomem *reg, u8 bit_idx, u8 cgr_val,
		void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 cgr_mask,
		u8 clk_gate2_flags, spinlock_t *lock,
		unsigned int *share_count)
{
@@ -157,6 +152,7 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
	gate->reg = reg;
	gate->bit_idx = bit_idx;
	gate->cgr_val = cgr_val;
	gate->cgr_mask = cgr_mask;
	gate->flags = clk_gate2_flags;
	gate->lock = lock;
	gate->share_count = share_count;
+1 −1
Original line number Diff line number Diff line
@@ -653,7 +653,7 @@ static struct platform_driver imx8mm_clk_driver = {
		 * reloading the driver will crash or break devices.
		 */
		.suppress_bind_attrs = true,
		.of_match_table = of_match_ptr(imx8mm_clk_of_match),
		.of_match_table = imx8mm_clk_of_match,
	},
};
module_platform_driver(imx8mm_clk_driver);
Loading