Unverified Commit e0129a0e authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'renesas-fixes-for-v5.14-tag1' of...

Merge tag 'renesas-fixes-for-v5.14-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into arm/fixes

Renesas fixes for v5.14

  - Fix a clock/reset handling design issue on the new RZ/G2L SoC,
    requiring an atomic change to DT binding definitions, clock driver,
    and DTS,
  - Restore graphical consoles in the shmobile_defconfig.

* tag 'renesas-fixes-for-v5.14-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel:
  ARM: shmobile: defconfig: Restore graphical consoles
  dt-bindings: clock: r9a07g044-cpg: Update clock/reset definitions
  clk: renesas: r9a07g044: Add P2 Clock support
  clk: renesas: r9a07g044: Fix P1 Clock
  clk: renesas: r9a07g044: Rename divider table
  clk: renesas: rzg2l: Add multi clock PM support

Link: https://lore.kernel.org/r/cover.1626253929.git.geert+renesas@glider.be


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents b6e473d1 432b52ee
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -135,6 +135,7 @@ CONFIG_DRM_SII902X=y
CONFIG_DRM_SIMPLE_BRIDGE=y
CONFIG_DRM_I2C_ADV7511=y
CONFIG_DRM_I2C_ADV7511_AUDIO=y
CONFIG_FB=y
CONFIG_FB_SH_MOBILE_LCDC=y
CONFIG_BACKLIGHT_PWM=y
CONFIG_BACKLIGHT_AS3711=y
+2 −2
Original line number Diff line number Diff line
@@ -82,10 +82,10 @@
				     <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>;
			interrupt-names = "eri", "rxi", "txi",
					  "bri", "dri", "tei";
			clocks = <&cpg CPG_MOD R9A07G044_CLK_SCIF0>;
			clocks = <&cpg CPG_MOD R9A07G044_SCIF0_CLK_PCK>;
			clock-names = "fck";
			power-domains = <&cpg>;
			resets = <&cpg R9A07G044_CLK_SCIF0>;
			resets = <&cpg R9A07G044_SCIF0_RST_SYSTEM_N>;
			status = "disabled";
		};

+47 −32
Original line number Diff line number Diff line
@@ -30,8 +30,9 @@ enum clk_ids {
	CLK_PLL2_DIV20,
	CLK_PLL3,
	CLK_PLL3_DIV2,
	CLK_PLL3_DIV2_4,
	CLK_PLL3_DIV2_4_2,
	CLK_PLL3_DIV4,
	CLK_PLL3_DIV8,
	CLK_PLL4,
	CLK_PLL5,
	CLK_PLL5_DIV2,
@@ -42,12 +43,13 @@ enum clk_ids {
};

/* Divider tables */
static const struct clk_div_table dtable_3b[] = {
static const struct clk_div_table dtable_1_32[] = {
	{0, 1},
	{1, 2},
	{2, 4},
	{3, 8},
	{4, 32},
	{0, 0},
};

static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
@@ -66,47 +68,56 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
	DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20),

	DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2),
	DEF_FIXED(".pll3_div2_4", CLK_PLL3_DIV2_4, CLK_PLL3_DIV2, 1, 4),
	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(".pll3_div8", CLK_PLL3_DIV8, CLK_PLL3, 1, 8),

	/* Core output clk */
	DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1),
	DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A,
		dtable_3b, CLK_DIVIDER_HIWORD_MASK),
		dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
	DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1),
	DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV8,
		DIVPL3B, dtable_3b, CLK_DIVIDER_HIWORD_MASK),
	DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4,
		DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
	DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2,
		DIVPL3A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
};

static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
	DEF_MOD("gic",		R9A07G044_CLK_GIC600,
				R9A07G044_CLK_P1,
				0x514, BIT(0), (BIT(0) | BIT(1))),
	DEF_MOD("ia55",		R9A07G044_CLK_IA55,
				R9A07G044_CLK_P1,
				0x518, (BIT(0) | BIT(1)), BIT(0)),
	DEF_MOD("scif0",	R9A07G044_CLK_SCIF0,
				R9A07G044_CLK_P0,
				0x584, BIT(0), BIT(0)),
	DEF_MOD("scif1",	R9A07G044_CLK_SCIF1,
				R9A07G044_CLK_P0,
				0x584, BIT(1), BIT(1)),
	DEF_MOD("scif2",	R9A07G044_CLK_SCIF2,
				R9A07G044_CLK_P0,
				0x584, BIT(2), BIT(2)),
	DEF_MOD("scif3",	R9A07G044_CLK_SCIF3,
				R9A07G044_CLK_P0,
				0x584, BIT(3), BIT(3)),
	DEF_MOD("scif4",	R9A07G044_CLK_SCIF4,
				R9A07G044_CLK_P0,
				0x584, BIT(4), BIT(4)),
	DEF_MOD("sci0",		R9A07G044_CLK_SCI0,
				R9A07G044_CLK_P0,
				0x588, BIT(0), BIT(0)),
	DEF_MOD("gic",		R9A07G044_GIC600_GICCLK, R9A07G044_CLK_P1,
				0x514, 0),
	DEF_MOD("ia55_pclk",	R9A07G044_IA55_PCLK, R9A07G044_CLK_P2,
				0x518, 0),
	DEF_MOD("ia55_clk",	R9A07G044_IA55_CLK, R9A07G044_CLK_P1,
				0x518, 1),
	DEF_MOD("scif0",	R9A07G044_SCIF0_CLK_PCK, R9A07G044_CLK_P0,
				0x584, 0),
	DEF_MOD("scif1",	R9A07G044_SCIF1_CLK_PCK, R9A07G044_CLK_P0,
				0x584, 1),
	DEF_MOD("scif2",	R9A07G044_SCIF2_CLK_PCK, R9A07G044_CLK_P0,
				0x584, 2),
	DEF_MOD("scif3",	R9A07G044_SCIF3_CLK_PCK, R9A07G044_CLK_P0,
				0x584, 3),
	DEF_MOD("scif4",	R9A07G044_SCIF4_CLK_PCK, R9A07G044_CLK_P0,
				0x584, 4),
	DEF_MOD("sci0",		R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0,
				0x588, 0),
};

static struct rzg2l_reset r9a07g044_resets[] = {
	DEF_RST(R9A07G044_GIC600_GICRESET_N, 0x814, 0),
	DEF_RST(R9A07G044_GIC600_DBG_GICRESET_N, 0x814, 1),
	DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0),
	DEF_RST(R9A07G044_SCIF0_RST_SYSTEM_N, 0x884, 0),
	DEF_RST(R9A07G044_SCIF1_RST_SYSTEM_N, 0x884, 1),
	DEF_RST(R9A07G044_SCIF2_RST_SYSTEM_N, 0x884, 2),
	DEF_RST(R9A07G044_SCIF3_RST_SYSTEM_N, 0x884, 3),
	DEF_RST(R9A07G044_SCIF4_RST_SYSTEM_N, 0x884, 4),
	DEF_RST(R9A07G044_SCI0_RST, 0x888, 0),
};

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

const struct rzg2l_cpg_info r9a07g044_cpg_info = {
@@ -123,5 +134,9 @@ const struct rzg2l_cpg_info r9a07g044_cpg_info = {
	/* Module Clocks */
	.mod_clks = r9a07g044_mod_clks,
	.num_mod_clks = ARRAY_SIZE(r9a07g044_mod_clks),
	.num_hw_mod_clks = R9A07G044_CLK_MIPI_DSI_PIN + 1,
	.num_hw_mod_clks = R9A07G044_TSU_PCLK + 1,

	/* Resets */
	.resets = r9a07g044_resets,
	.num_resets = ARRAY_SIZE(r9a07g044_resets),
};
+59 −51
Original line number Diff line number Diff line
@@ -47,9 +47,9 @@
#define SDIV(val)		DIV_RSMASK(val, 0, 0x7)

#define CLK_ON_R(reg)		(reg)
#define CLK_MON_R(reg)		(0x680 - 0x500 + (reg))
#define CLK_RST_R(reg)		(0x800 - 0x500 + (reg))
#define CLK_MRST_R(reg)		(0x980 - 0x500 + (reg))
#define CLK_MON_R(reg)		(0x180 + (reg))
#define CLK_RST_R(reg)		(reg)
#define CLK_MRST_R(reg)		(0x180 + (reg))

#define GET_REG_OFFSET(val)		((val >> 20) & 0xfff)
#define GET_REG_SAMPLL_CLK1(val)	((val >> 22) & 0xfff)
@@ -78,6 +78,7 @@ struct rzg2l_cpg_priv {
	struct clk **clks;
	unsigned int num_core_clks;
	unsigned int num_mod_clks;
	unsigned int num_resets;
	unsigned int last_dt_core_clk;

	struct raw_notifier_head notifiers;
@@ -315,15 +316,13 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
 *
 * @hw: handle between common and hardware-specific interfaces
 * @off: register offset
 * @onoff: ON/MON bits
 * @reset: reset bits
 * @bit: ON/MON bit
 * @priv: CPG/MSTP private data
 */
struct mstp_clock {
	struct clk_hw hw;
	u16 off;
	u8 onoff;
	u8 reset;
	u8 bit;
	struct rzg2l_cpg_priv *priv;
};

@@ -337,6 +336,7 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)
	struct device *dev = priv->dev;
	unsigned long flags;
	unsigned int i;
	u32 bitmask = BIT(clock->bit);
	u32 value;

	if (!clock->off) {
@@ -349,9 +349,9 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)
	spin_lock_irqsave(&priv->rmw_lock, flags);

	if (enable)
		value = (clock->onoff << 16) | clock->onoff;
		value = (bitmask << 16) | bitmask;
	else
		value = clock->onoff << 16;
		value = bitmask << 16;
	writel(value, priv->base + CLK_ON_R(reg));

	spin_unlock_irqrestore(&priv->rmw_lock, flags);
@@ -360,7 +360,7 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)
		return 0;

	for (i = 1000; i > 0; --i) {
		if (((readl(priv->base + CLK_MON_R(reg))) & clock->onoff))
		if (((readl(priv->base + CLK_MON_R(reg))) & bitmask))
			break;
		cpu_relax();
	}
@@ -388,6 +388,7 @@ static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw)
{
	struct mstp_clock *clock = to_mod_clock(hw);
	struct rzg2l_cpg_priv *priv = clock->priv;
	u32 bitmask = BIT(clock->bit);
	u32 value;

	if (!clock->off) {
@@ -397,7 +398,7 @@ static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw)

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

	return !(value & clock->onoff);
	return !(value & bitmask);
}

static const struct clk_ops rzg2l_mod_clock_ops = {
@@ -457,8 +458,7 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod,
	init.num_parents = 1;

	clock->off = mod->off;
	clock->onoff = mod->onoff;
	clock->reset = mod->reset;
	clock->bit = mod->bit;
	clock->priv = priv;
	clock->hw.init = &init;

@@ -483,12 +483,11 @@ static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev,
{
	struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
	const struct rzg2l_cpg_info *info = priv->info;
	unsigned int reg = info->mod_clks[id].off;
	u32 dis = info->mod_clks[id].reset;
	unsigned int reg = info->resets[id].off;
	u32 dis = BIT(info->resets[id].bit);
	u32 we = dis << 16;

	dev_dbg(rcdev->dev, "reset name:%s id:%ld offset:0x%x\n",
		info->mod_clks[id].name, id, CLK_RST_R(reg));
	dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg));

	/* Reset module */
	writel(we, priv->base + CLK_RST_R(reg));
@@ -507,11 +506,10 @@ static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev,
{
	struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
	const struct rzg2l_cpg_info *info = priv->info;
	unsigned int reg = info->mod_clks[id].off;
	u32 value = info->mod_clks[id].reset << 16;
	unsigned int reg = info->resets[id].off;
	u32 value = BIT(info->resets[id].bit) << 16;

	dev_dbg(rcdev->dev, "assert name:%s id:%ld offset:0x%x\n",
		info->mod_clks[id].name, id, CLK_RST_R(reg));
	dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg));

	writel(value, priv->base + CLK_RST_R(reg));
	return 0;
@@ -522,12 +520,12 @@ static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev,
{
	struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
	const struct rzg2l_cpg_info *info = priv->info;
	unsigned int reg = info->mod_clks[id].off;
	u32 dis = info->mod_clks[id].reset;
	unsigned int reg = info->resets[id].off;
	u32 dis = BIT(info->resets[id].bit);
	u32 value = (dis << 16) | dis;

	dev_dbg(rcdev->dev, "deassert name:%s id:%ld offset:0x%x\n",
		info->mod_clks[id].name, id, CLK_RST_R(reg));
	dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id,
		CLK_RST_R(reg));

	writel(value, priv->base + CLK_RST_R(reg));
	return 0;
@@ -538,8 +536,8 @@ static int rzg2l_cpg_status(struct reset_controller_dev *rcdev,
{
	struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
	const struct rzg2l_cpg_info *info = priv->info;
	unsigned int reg = info->mod_clks[id].off;
	u32 bitmask = info->mod_clks[id].reset;
	unsigned int reg = info->resets[id].off;
	u32 bitmask = BIT(info->resets[id].bit);

	return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask);
}
@@ -554,9 +552,11 @@ static const struct reset_control_ops rzg2l_cpg_reset_ops = {
static int rzg2l_cpg_reset_xlate(struct reset_controller_dev *rcdev,
				 const struct of_phandle_args *reset_spec)
{
	struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
	const struct rzg2l_cpg_info *info = priv->info;
	unsigned int id = reset_spec->args[0];

	if (id >= rcdev->nr_resets) {
	if (id >= rcdev->nr_resets || !info->resets[id].off) {
		dev_err(rcdev->dev, "Invalid reset index %u\n", id);
		return -EINVAL;
	}
@@ -571,7 +571,7 @@ static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv)
	priv->rcdev.dev = priv->dev;
	priv->rcdev.of_reset_n_cells = 1;
	priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate;
	priv->rcdev.nr_resets = priv->num_mod_clks;
	priv->rcdev.nr_resets = priv->num_resets;

	return devm_reset_controller_register(priv->dev, &priv->rcdev);
}
@@ -594,42 +594,49 @@ static int rzg2l_cpg_attach_dev(struct generic_pm_domain *unused, struct device
{
	struct device_node *np = dev->of_node;
	struct of_phandle_args clkspec;
	bool once = true;
	struct clk *clk;
	int error;
	int i = 0;

	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
					   &clkspec)) {
		if (rzg2l_cpg_is_pm_clk(&clkspec))
			goto found;

		if (rzg2l_cpg_is_pm_clk(&clkspec)) {
			if (once) {
				once = false;
				error = pm_clk_create(dev);
				if (error) {
					of_node_put(clkspec.np);
		i++;
					goto err;
				}
			}

	return 0;

found:
			clk = of_clk_get_from_provider(&clkspec);
			of_node_put(clkspec.np);

	if (IS_ERR(clk))
		return PTR_ERR(clk);

	error = pm_clk_create(dev);
	if (error)
		goto fail_put;
			if (IS_ERR(clk)) {
				error = PTR_ERR(clk);
				goto fail_destroy;
			}

			error = pm_clk_add_clk(dev, clk);
	if (error)
		goto fail_destroy;
			if (error) {
				dev_err(dev, "pm_clk_add_clk failed %d\n",
					error);
				goto fail_put;
			}
		} else {
			of_node_put(clkspec.np);
		}
		i++;
	}

	return 0;

fail_destroy:
	pm_clk_destroy(dev);
fail_put:
	clk_put(clk);

fail_destroy:
	pm_clk_destroy(dev);
err:
	return error;
}

@@ -692,6 +699,7 @@ static int __init rzg2l_cpg_probe(struct platform_device *pdev)
	priv->clks = clks;
	priv->num_core_clks = info->num_total_core_clks;
	priv->num_mod_clks = info->num_hw_mod_clks;
	priv->num_resets = info->num_resets;
	priv->last_dt_core_clk = info->last_dt_core_clk;

	for (i = 0; i < nclks; i++)
+28 −9
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#define DDIV_PACK(offset, bitpos, size) \
		(((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
#define DIVPL2A		DDIV_PACK(CPG_PL2_DDIV, 0, 3)
#define DIVPL3A		DDIV_PACK(CPG_PL3A_DDIV, 0, 3)
#define DIVPL3B		DDIV_PACK(CPG_PL3A_DDIV, 4, 3)

/**
@@ -76,26 +77,40 @@ enum clk_types {
 * @id: clock index in array containing all Core and Module Clocks
 * @parent: id of parent clock
 * @off: register offset
 * @onoff: ON/MON bits
 * @reset: reset bits
 * @bit: ON/MON bit
 */
struct rzg2l_mod_clk {
	const char *name;
	unsigned int id;
	unsigned int parent;
	u16 off;
	u8 onoff;
	u8 reset;
	u8 bit;
};

#define DEF_MOD(_name, _id, _parent, _off, _onoff, _reset)	\
	[_id] = { \
#define DEF_MOD(_name, _id, _parent, _off, _bit)	\
	{ \
		.name = _name, \
		.id = MOD_CLK_BASE + _id, \
		.id = MOD_CLK_BASE + (_id), \
		.parent = (_parent), \
		.off = (_off), \
		.onoff = (_onoff), \
		.reset = (_reset) \
		.bit = (_bit), \
	}

/**
 * struct rzg2l_reset - Reset definitions
 *
 * @off: register offset
 * @bit: reset bit
 */
struct rzg2l_reset {
	u16 off;
	u8 bit;
};

#define DEF_RST(_id, _off, _bit)	\
	[_id] = { \
		.off = (_off), \
		.bit = (_bit) \
	}

/**
@@ -126,6 +141,10 @@ struct rzg2l_cpg_info {
	unsigned int num_mod_clks;
	unsigned int num_hw_mod_clks;

	/* Resets */
	const struct rzg2l_reset *resets;
	unsigned int num_resets;

	/* Critical Module Clocks that should not be disabled */
	const unsigned int *crit_mod_clks;
	unsigned int num_crit_mod_clks;
Loading