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

Merge tag 'renesas-clk-for-v5.16-tag1' of...

Merge tag 'renesas-clk-for-v5.16-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into clk-renesas

Pull Renesas clk driver updates from Geert Uytterhoeven:

 - Add TPU (PWM), and Z (Cortex-A76) clocks on Renesas R-Car V3U
 - Add Ethernet clocks on Renesas RZ/G2L

* tag 'renesas-clk-for-v5.16-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers:
  clk: renesas: r8a779a0: Add Z0 and Z1 clock support
  clk: renesas: r9a07g044: Add GbEthernet clock/reset
  clk: renesas: rzg2l: Add support to handle coupled clocks
  clk: renesas: r9a07g044: Add ethernet clock sources
  clk: renesas: rzg2l: Add support to handle MUX clocks
  clk: renesas: r8a779a0: Add TPU clock
  clk: renesas: rzg2l: Fix clk status function
  clk: renesas: r9a07g044: Mark IA55_CLK and DMAC_ACLK critical
parents 6880fa6c cc3e8f97
Loading
Loading
Loading
Loading
+159 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ enum rcar_r8a779a0_clk_types {
	CLK_TYPE_R8A779A0_PLL1,
	CLK_TYPE_R8A779A0_PLL2X_3X,	/* PLL[23][01] */
	CLK_TYPE_R8A779A0_PLL5,
	CLK_TYPE_R8A779A0_Z,
	CLK_TYPE_R8A779A0_SD,
	CLK_TYPE_R8A779A0_MDSEL,	/* Select parent/divider using mode pin */
	CLK_TYPE_R8A779A0_OSC,	/* OSC EXTAL predivider and fixed divider */
@@ -84,6 +85,10 @@ enum clk_ids {
	DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_PLL2X_3X, CLK_MAIN, \
		 .offset = _offset)

#define DEF_Z(_name, _id, _parent, _div, _offset)	\
	DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_Z, _parent, .div = _div,	\
		 .offset = _offset)

#define DEF_SD(_name, _id, _parent, _offset)   \
	DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_SD, _parent, .offset = _offset)

@@ -122,6 +127,8 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
	DEF_RATE(".oco",		CLK_OCO,	32768),

	/* Core Clock Outputs */
	DEF_Z("z0",		R8A779A0_CLK_Z0,	CLK_PLL20,	2, 0),
	DEF_Z("z1",		R8A779A0_CLK_Z1,	CLK_PLL21,	2, 8),
	DEF_FIXED("zx",		R8A779A0_CLK_ZX,	CLK_PLL20_DIV2,	2, 1),
	DEF_FIXED("s1d1",	R8A779A0_CLK_S1D1,	CLK_S1,		1, 1),
	DEF_FIXED("s1d2",	R8A779A0_CLK_S1D2,	CLK_S1,		2, 1),
@@ -205,6 +212,7 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = {
	DEF_MOD("tmu2",		715,	R8A779A0_CLK_S1D4),
	DEF_MOD("tmu3",		716,	R8A779A0_CLK_S1D4),
	DEF_MOD("tmu4",		717,	R8A779A0_CLK_S1D4),
	DEF_MOD("tpu0",		718,	R8A779A0_CLK_S1D8),
	DEF_MOD("vin00",	730,	R8A779A0_CLK_S1D1),
	DEF_MOD("vin01",	731,	R8A779A0_CLK_S1D1),
	DEF_MOD("vin02",	800,	R8A779A0_CLK_S1D1),
@@ -259,6 +267,153 @@ static const struct rcar_r8a779a0_cpg_pll_config *cpg_pll_config __initdata;
static unsigned int cpg_clk_extalr __initdata;
static u32 cpg_mode __initdata;

/*
 * Z0 Clock & Z1 Clock
 */
#define CPG_FRQCRB			0x00000804
#define CPG_FRQCRB_KICK			BIT(31)
#define CPG_FRQCRC			0x00000808

struct cpg_z_clk {
	struct clk_hw hw;
	void __iomem *reg;
	void __iomem *kick_reg;
	unsigned long max_rate;		/* Maximum rate for normal mode */
	unsigned int fixed_div;
	u32 mask;
};

#define to_z_clk(_hw)	container_of(_hw, struct cpg_z_clk, hw)

static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
					   unsigned long parent_rate)
{
	struct cpg_z_clk *zclk = to_z_clk(hw);
	unsigned int mult;
	u32 val;

	val = readl(zclk->reg) & zclk->mask;
	mult = 32 - (val >> __ffs(zclk->mask));

	return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult,
				     32 * zclk->fixed_div);
}

static int cpg_z_clk_determine_rate(struct clk_hw *hw,
				    struct clk_rate_request *req)
{
	struct cpg_z_clk *zclk = to_z_clk(hw);
	unsigned int min_mult, max_mult, mult;
	unsigned long rate, prate;

	rate = min(req->rate, req->max_rate);
	if (rate <= zclk->max_rate) {
		/* Set parent rate to initial value for normal modes */
		prate = zclk->max_rate;
	} else {
		/* Set increased parent rate for boost modes */
		prate = rate;
	}
	req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
						  prate * zclk->fixed_div);

	prate = req->best_parent_rate / zclk->fixed_div;
	min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL);
	max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL);
	if (max_mult < min_mult)
		return -EINVAL;

	mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL, prate);
	mult = clamp(mult, min_mult, max_mult);

	req->rate = DIV_ROUND_CLOSEST_ULL((u64)prate * mult, 32);
	return 0;
}

static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
			      unsigned long parent_rate)
{
	struct cpg_z_clk *zclk = to_z_clk(hw);
	unsigned int mult;
	unsigned int i;

	mult = DIV64_U64_ROUND_CLOSEST(rate * 32ULL * zclk->fixed_div,
				       parent_rate);
	mult = clamp(mult, 1U, 32U);

	if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
		return -EBUSY;

	cpg_reg_modify(zclk->reg, zclk->mask, (32 - mult) << __ffs(zclk->mask));

	/*
	 * Set KICK bit in FRQCRB to update hardware setting and wait for
	 * clock change completion.
	 */
	cpg_reg_modify(zclk->kick_reg, 0, CPG_FRQCRB_KICK);

	/*
	 * Note: There is no HW information about the worst case latency.
	 *
	 * Using experimental measurements, it seems that no more than
	 * ~10 iterations are needed, independently of the CPU rate.
	 * Since this value might be dependent on external xtal rate, pll1
	 * rate or even the other emulation clocks rate, use 1000 as a
	 * "super" safe value.
	 */
	for (i = 1000; i; i--) {
		if (!(readl(zclk->kick_reg) & CPG_FRQCRB_KICK))
			return 0;

		cpu_relax();
	}

	return -ETIMEDOUT;
}

static const struct clk_ops cpg_z_clk_ops = {
	.recalc_rate = cpg_z_clk_recalc_rate,
	.determine_rate = cpg_z_clk_determine_rate,
	.set_rate = cpg_z_clk_set_rate,
};

static struct clk * __init cpg_z_clk_register(const char *name,
					      const char *parent_name,
					      void __iomem *reg,
					      unsigned int div,
					      unsigned int offset)
{
	struct clk_init_data init = {};
	struct cpg_z_clk *zclk;
	struct clk *clk;

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

	init.name = name;
	init.ops = &cpg_z_clk_ops;
	init.flags = CLK_SET_RATE_PARENT;
	init.parent_names = &parent_name;
	init.num_parents = 1;

	zclk->reg = reg + CPG_FRQCRC;
	zclk->kick_reg = reg + CPG_FRQCRB;
	zclk->hw.init = &init;
	zclk->mask = GENMASK(offset + 4, offset);
	zclk->fixed_div = div; /* PLLVCO x 1/div x SYS-CPU divider */

	clk = clk_register(NULL, &zclk->hw);
	if (IS_ERR(clk)) {
		kfree(zclk);
		return clk;
	}

	zclk->max_rate = clk_hw_get_rate(clk_hw_get_parent(&zclk->hw)) /
			 zclk->fixed_div;
	return clk;
}

static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev,
	const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
	struct clk **clks, void __iomem *base,
@@ -293,6 +448,10 @@ static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev,
		div = cpg_pll_config->pll5_div;
		break;

	case CLK_TYPE_R8A779A0_Z:
		return cpg_z_clk_register(core->name, __clk_get_name(parent),
					  base, core->div, core->offset);

	case CLK_TYPE_R8A779A0_SD:
		return cpg_sd_clk_register(core->name, base, core->offset,
					   __clk_get_name(parent), notifiers,
+30 −1
Original line number Diff line number Diff line
@@ -35,8 +35,10 @@ enum clk_ids {
	CLK_PLL3_DIV4,
	CLK_PLL4,
	CLK_PLL5,
	CLK_PLL5_DIV2,
	CLK_PLL5_FOUT3,
	CLK_PLL5_250,
	CLK_PLL6,
	CLK_PLL6_250,
	CLK_P1_DIV2,

	/* Module Clocks */
@@ -53,6 +55,9 @@ static const struct clk_div_table dtable_1_32[] = {
	{0, 0},
};

/* Mux clock tables */
static const char * const sel_pll6_2[]	= { ".pll6_250", ".pll5_250" };

static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
	/* External Clock Inputs */
	DEF_INPUT("extal", CLK_EXTAL),
@@ -64,6 +69,11 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
	DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 133, 2),
	DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 133, 2),

	DEF_FIXED(".pll5", CLK_PLL5, CLK_EXTAL, 125, 1),
	DEF_FIXED(".pll5_fout3", CLK_PLL5_FOUT3, CLK_PLL5, 1, 6),

	DEF_FIXED(".pll6", CLK_PLL6, CLK_EXTAL, 125, 6),

	DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2),
	DEF_FIXED(".pll2_div16", CLK_PLL2_DIV16, CLK_PLL2, 1, 16),
	DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20),
@@ -73,6 +83,9 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
	DEF_FIXED(".pll3_div2_4_2", CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV2_4, 1, 2),
	DEF_FIXED(".pll3_div4", CLK_PLL3_DIV4, CLK_PLL3, 1, 4),

	DEF_FIXED(".pll5_250", CLK_PLL5_250, CLK_PLL5_FOUT3, 1, 2),
	DEF_FIXED(".pll6_250", CLK_PLL6_250, CLK_PLL6, 1, 2),

	/* Core output clk */
	DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1),
	DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A,
@@ -84,6 +97,10 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
	DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2),
	DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2,
		DIVPL3A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
	DEF_FIXED("M0", R9A07G044_CLK_M0, CLK_PLL3_DIV2_4, 1, 1),
	DEF_FIXED("ZT", R9A07G044_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1),
	DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2,
		sel_pll6_2, ARRAY_SIZE(sel_pll6_2), 0, CLK_MUX_HIWORD_MASK),
};

static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
@@ -121,6 +138,14 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
				0x578, 2),
	DEF_MOD("usb_pclk",	R9A07G044_USB_PCLK, R9A07G044_CLK_P1,
				0x578, 3),
	DEF_COUPLED("eth0_axi",	R9A07G044_ETH0_CLK_AXI, R9A07G044_CLK_M0,
				0x57c, 0),
	DEF_COUPLED("eth0_chi",	R9A07G044_ETH0_CLK_CHI, R9A07G044_CLK_ZT,
				0x57c, 0),
	DEF_COUPLED("eth1_axi",	R9A07G044_ETH1_CLK_AXI, R9A07G044_CLK_M0,
				0x57c, 1),
	DEF_COUPLED("eth1_chi",	R9A07G044_ETH1_CLK_CHI, R9A07G044_CLK_ZT,
				0x57c, 1),
	DEF_MOD("i2c0",		R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0,
				0x580, 0),
	DEF_MOD("i2c1",		R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0,
@@ -165,6 +190,8 @@ static struct rzg2l_reset r9a07g044_resets[] = {
	DEF_RST(R9A07G044_USB_U2H1_HRESETN, 0x878, 1),
	DEF_RST(R9A07G044_USB_U2P_EXL_SYSRST, 0x878, 2),
	DEF_RST(R9A07G044_USB_PRESETN, 0x878, 3),
	DEF_RST(R9A07G044_ETH0_RST_HW_N, 0x87c, 0),
	DEF_RST(R9A07G044_ETH1_RST_HW_N, 0x87c, 1),
	DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0),
	DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1),
	DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2),
@@ -186,6 +213,8 @@ static struct rzg2l_reset r9a07g044_resets[] = {

static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
	MOD_CLK_BASE + R9A07G044_GIC600_GICCLK,
	MOD_CLK_BASE + R9A07G044_IA55_CLK,
	MOD_CLK_BASE + R9A07G044_DMAC_ACLK,
};

const struct rzg2l_cpg_info r9a07g044_cpg_info = {
+95 −1
Original line number Diff line number Diff line
@@ -130,6 +130,26 @@ rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core,
	return clk_hw->clk;
}

static struct clk * __init
rzg2l_cpg_mux_clk_register(const struct cpg_core_clk *core,
			   void __iomem *base,
			   struct rzg2l_cpg_priv *priv)
{
	const struct clk_hw *clk_hw;

	clk_hw = devm_clk_hw_register_mux(priv->dev, core->name,
					  core->parent_names, core->num_parents,
					  core->flag,
					  base + GET_REG_OFFSET(core->conf),
					  GET_SHIFT(core->conf),
					  GET_WIDTH(core->conf),
					  core->mux_flags, &priv->rmw_lock);
	if (IS_ERR(clk_hw))
		return ERR_CAST(clk_hw);

	return clk_hw->clk;
}

struct pll_clk {
	struct clk_hw hw;
	unsigned int conf;
@@ -288,6 +308,9 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
		clk = rzg2l_cpg_div_clk_register(core, priv->clks,
						 priv->base, priv);
		break;
	case CLK_TYPE_MUX:
		clk = rzg2l_cpg_mux_clk_register(core, priv->base, priv);
		break;
	default:
		goto fail;
	}
@@ -310,13 +333,17 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
 * @hw: handle between common and hardware-specific interfaces
 * @off: register offset
 * @bit: ON/MON bit
 * @enabled: soft state of the clock, if it is coupled with another clock
 * @priv: CPG/MSTP private data
 * @sibling: pointer to the other coupled clock
 */
struct mstp_clock {
	struct clk_hw hw;
	u16 off;
	u8 bit;
	bool enabled;
	struct rzg2l_cpg_priv *priv;
	struct mstp_clock *sibling;
};

#define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw)
@@ -369,11 +396,41 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)

static int rzg2l_mod_clock_enable(struct clk_hw *hw)
{
	struct mstp_clock *clock = to_mod_clock(hw);

	if (clock->sibling) {
		struct rzg2l_cpg_priv *priv = clock->priv;
		unsigned long flags;
		bool enabled;

		spin_lock_irqsave(&priv->rmw_lock, flags);
		enabled = clock->sibling->enabled;
		clock->enabled = true;
		spin_unlock_irqrestore(&priv->rmw_lock, flags);
		if (enabled)
			return 0;
	}

	return rzg2l_mod_clock_endisable(hw, true);
}

static void rzg2l_mod_clock_disable(struct clk_hw *hw)
{
	struct mstp_clock *clock = to_mod_clock(hw);

	if (clock->sibling) {
		struct rzg2l_cpg_priv *priv = clock->priv;
		unsigned long flags;
		bool enabled;

		spin_lock_irqsave(&priv->rmw_lock, flags);
		enabled = clock->sibling->enabled;
		clock->enabled = false;
		spin_unlock_irqrestore(&priv->rmw_lock, flags);
		if (enabled)
			return;
	}

	rzg2l_mod_clock_endisable(hw, false);
}

@@ -389,9 +446,12 @@ static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw)
		return 1;
	}

	if (clock->sibling)
		return clock->enabled;

	value = readl(priv->base + CLK_MON_R(clock->off));

	return !(value & bitmask);
	return value & bitmask;
}

static const struct clk_ops rzg2l_mod_clock_ops = {
@@ -400,6 +460,28 @@ static const struct clk_ops rzg2l_mod_clock_ops = {
	.is_enabled = rzg2l_mod_clock_is_enabled,
};

static struct mstp_clock
*rzg2l_mod_clock__get_sibling(struct mstp_clock *clock,
			      struct rzg2l_cpg_priv *priv)
{
	struct clk_hw *hw;
	unsigned int i;

	for (i = 0; i < priv->num_mod_clks; i++) {
		struct mstp_clock *clk;

		if (priv->clks[priv->num_core_clks + i] == ERR_PTR(-ENOENT))
			continue;

		hw = __clk_get_hw(priv->clks[priv->num_core_clks + i]);
		clk = to_mod_clock(hw);
		if (clock->off == clk->off && clock->bit == clk->bit)
			return clk;
	}

	return NULL;
}

static void __init
rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod,
			   const struct rzg2l_cpg_info *info,
@@ -461,6 +543,18 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod,

	dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
	priv->clks[id] = clk;

	if (mod->is_coupled) {
		struct mstp_clock *sibling;

		clock->enabled = rzg2l_mod_clock_is_enabled(&clock->hw);
		sibling = rzg2l_mod_clock__get_sibling(clock, priv);
		if (sibling) {
			clock->sibling = sibling;
			sibling->sibling = clock;
		}
	}

	return;

fail:
+25 −1
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@

#define CPG_PL2_DDIV		(0x204)
#define CPG_PL3A_DDIV		(0x208)
#define CPG_PL6_ETH_SSEL	(0x418)

/* n = 0/1/2 for PLL1/4/6 */
#define CPG_SAMPLL_CLK1(n)	(0x04 + (16 * n))
@@ -24,6 +25,11 @@
#define DIVPL3A		DDIV_PACK(CPG_PL3A_DDIV, 0, 3)
#define DIVPL3B		DDIV_PACK(CPG_PL3A_DDIV, 4, 3)

#define SEL_PLL_PACK(offset, bitpos, size) \
		(((offset) << 20) | ((bitpos) << 12) | ((size) << 8))

#define SEL_PLL6_2	SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1)

/**
 * Definitions of CPG Core Clocks
 *
@@ -43,6 +49,7 @@ struct cpg_core_clk {
	const struct clk_div_table *dtable;
	const char * const *parent_names;
	int flag;
	int mux_flags;
	int num_parents;
};

@@ -54,6 +61,9 @@ enum clk_types {

	/* Clock with divider */
	CLK_TYPE_DIV,

	/* Clock with clock source selector */
	CLK_TYPE_MUX,
};

#define DEF_TYPE(_name, _id, _type...) \
@@ -69,6 +79,11 @@ enum clk_types {
#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \
	DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \
		 .parent = _parent, .dtable = _dtable, .flag = _flag)
#define DEF_MUX(_name, _id, _conf, _parent_names, _num_parents, _flag, \
		_mux_flags) \
	DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \
		 .parent_names = _parent_names, .num_parents = _num_parents, \
		 .flag = _flag, .mux_flags = _mux_flags)

/**
 * struct rzg2l_mod_clk - Module Clocks definitions
@@ -78,6 +93,7 @@ enum clk_types {
 * @parent: id of parent clock
 * @off: register offset
 * @bit: ON/MON bit
 * @is_coupled: flag to indicate coupled clock
 */
struct rzg2l_mod_clk {
	const char *name;
@@ -85,17 +101,25 @@ struct rzg2l_mod_clk {
	unsigned int parent;
	u16 off;
	u8 bit;
	bool is_coupled;
};

#define DEF_MOD(_name, _id, _parent, _off, _bit)	\
#define DEF_MOD_BASE(_name, _id, _parent, _off, _bit, _is_coupled)	\
	{ \
		.name = _name, \
		.id = MOD_CLK_BASE + (_id), \
		.parent = (_parent), \
		.off = (_off), \
		.bit = (_bit), \
		.is_coupled = (_is_coupled), \
	}

#define DEF_MOD(_name, _id, _parent, _off, _bit)	\
	DEF_MOD_BASE(_name, _id, _parent, _off, _bit, false)

#define DEF_COUPLED(_name, _id, _parent, _off, _bit)	\
	DEF_MOD_BASE(_name, _id, _parent, _off, _bit, true)

/**
 * struct rzg2l_reset - Reset definitions
 *