Commit b9d0b84b authored by Geert Uytterhoeven's avatar Geert Uytterhoeven
Browse files

clk: renesas: rcar-gen3: Add support for RCKSEL clock selection



Add a clock type and macro for defining clocks where the parent and
divider are selected based on the value of the RCKCR.CKSEL bit.

Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: default avatarSimon Horman <horms+renesas@verge.net.au>
parent 0d2602d7
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
/*
 * R-Car Gen3 Clock Pulse Generator
 *
 * Copyright (C) 2015-2016 Glider bvba
 * Copyright (C) 2015-2018 Glider bvba
 *
 * Based on clk-rcar-gen3.c
 *
@@ -31,6 +31,8 @@
#define CPG_PLL2CR		0x002c
#define CPG_PLL4CR		0x01f4

#define CPG_RCKCR_CKSEL	BIT(15)	/* RCLK Clock Source Select */

struct cpg_simple_notifier {
	struct notifier_block nb;
	void __iomem *reg;
@@ -444,7 +446,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
	unsigned int div = 1;
	u32 value;

	parent = clks[core->parent & 0xffff];	/* CLK_TYPE_PE uses high bits */
	parent = clks[core->parent & 0xffff];	/* some types use high bits */
	if (IS_ERR(parent))
		return ERR_CAST(parent);

@@ -524,7 +526,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,

			if (clk_get_rate(clks[cpg_clk_extalr])) {
				parent = clks[cpg_clk_extalr];
				value |= BIT(15);
				value |= CPG_RCKCR_CKSEL;
			}

			writel(value, csn->reg);
@@ -570,6 +572,21 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
		div = cpg_pll_config->osc_prediv * core->div;
		break;

	case CLK_TYPE_GEN3_RCKSEL:
		/*
		 * Clock selectable between two parents and two fixed dividers
		 * using RCKCR.CKSEL
		 */
		if (readl(base + CPG_RCKCR) & CPG_RCKCR_CKSEL) {
			div = core->div & 0xffff;
		} else {
			parent = clks[core->parent >> 16];
			if (IS_ERR(parent))
				return ERR_CAST(parent);
			div = core->div >> 16;
		}
		break;

	default:
		return ERR_PTR(-EINVAL);
	}
+6 −1
Original line number Diff line number Diff line
/*
 * R-Car Gen3 Clock Pulse Generator
 *
 * Copyright (C) 2015-2016 Glider bvba
 * Copyright (C) 2015-2018 Glider bvba
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@ enum rcar_gen3_clk_types {
	CLK_TYPE_GEN3_Z,
	CLK_TYPE_GEN3_Z2,
	CLK_TYPE_GEN3_OSC,	/* OSC EXTAL predivider and fixed divider */
	CLK_TYPE_GEN3_RCKSEL,	/* Select parent/divider using RCKCR.CKSEL */
};

#define DEF_GEN3_SD(_name, _id, _parent, _offset)	\
@@ -37,6 +38,10 @@ enum rcar_gen3_clk_types {
#define DEF_GEN3_OSC(_name, _id, _parent, _div)		\
	DEF_BASE(_name, _id, CLK_TYPE_GEN3_OSC, _parent, .div = _div)

#define DEF_GEN3_RCKSEL(_name, _id, _parent0, _div0, _parent1, _div1) \
	DEF_BASE(_name, _id, CLK_TYPE_GEN3_RCKSEL,	\
		 (_parent0) << 16 | (_parent1),	.div = (_div0) << 16 | (_div1))

struct rcar_gen3_cpg_pll_config {
	u8 extal_div;
	u8 pll1_mult;