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

Commit 47727beb authored by Loc Ho's avatar Loc Ho Committed by Stephen Boyd
Browse files

clk: xgene: Add SoC and PMD PLL clocks with v2 hardware



Add X-Gene SoC and PMD PLL clocks support for v2 hardware.
X-Gene SoC v2 and above use an slightly different SoC
and PMD PLL hardware logic.

Signed-off-by: default avatarLoc Ho <lho@apm.com>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent 7b63c567
Loading
Loading
Loading
Loading
+66 −37
Original line number Diff line number Diff line
@@ -29,7 +29,9 @@
#include <linux/of_address.h>

/* Register SCU_PCPPLL bit fields */
#define N_DIV_RD(src)			(((src) & 0x000001ff))
#define N_DIV_RD(src)			((src) & 0x000001ff)
#define SC_N_DIV_RD(src)		((src) & 0x0000007f)
#define SC_OUTDIV2(src)			(((src) & 0x00000100) >> 8)

/* Register SCU_SOCPLL bit fields */
#define CLKR_RD(src)			(((src) & 0x07000000)>>24)
@@ -63,6 +65,7 @@ struct xgene_clk_pll {
	spinlock_t	*lock;
	u32		pll_offset;
	enum xgene_pll_type	type;
	int		version;
};

#define to_xgene_clk_pll(_hw) container_of(_hw, struct xgene_clk_pll, hw)
@@ -92,6 +95,7 @@ static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw,

	pll = xgene_clk_read(pllclk->reg + pllclk->pll_offset);

	if (pllclk->version <= 1) {
		if (pllclk->type == PLL_TYPE_PCP) {
			/*
			* PLL VCO = Reference clock * NF
@@ -111,8 +115,17 @@ static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw,
			fref = parent_rate / nref;
			fvco = fref * nfb;
		}
	pr_debug("%s pll recalc rate %ld parent %ld\n", clk_hw_get_name(hw),
		fvco / nout, parent_rate);
	} else {
		/*
		 * fvco = Reference clock * FBDIVC
		 * PLL freq = fvco / NOUT
		 */
		nout = SC_OUTDIV2(pll) ? 2 : 3;
		fvco = parent_rate * SC_N_DIV_RD(pll);
	}
	pr_debug("%s pll recalc rate %ld parent %ld version %d\n",
		 clk_hw_get_name(hw), fvco / nout, parent_rate,
		 pllclk->version);

	return fvco / nout;
}
@@ -125,7 +138,7 @@ static const struct clk_ops xgene_clk_pll_ops = {
static struct clk *xgene_register_clk_pll(struct device *dev,
	const char *name, const char *parent_name,
	unsigned long flags, void __iomem *reg, u32 pll_offset,
	u32 type, spinlock_t *lock)
	u32 type, spinlock_t *lock, int version)
{
	struct xgene_clk_pll *apmclk;
	struct clk *clk;
@@ -144,6 +157,7 @@ static struct clk *xgene_register_clk_pll(struct device *dev,
	init.parent_names = parent_name ? &parent_name : NULL;
	init.num_parents = parent_name ? 1 : 0;

	apmclk->version = version;
	apmclk->reg = reg;
	apmclk->lock = lock;
	apmclk->pll_offset = pll_offset;
@@ -160,11 +174,21 @@ static struct clk *xgene_register_clk_pll(struct device *dev,
	return clk;
}

static int xgene_pllclk_version(struct device_node *np)
{
	if (of_device_is_compatible(np, "apm,xgene-socpll-clock"))
		return 1;
	if (of_device_is_compatible(np, "apm,xgene-pcppll-clock"))
		return 1;
	return 2;
}

static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_type)
{
	const char *clk_name = np->full_name;
	struct clk *clk;
	void __iomem *reg;
	int version = xgene_pllclk_version(np);

	reg = of_iomap(np, 0);
	if (reg == NULL) {
@@ -174,7 +198,8 @@ static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_ty
	of_property_read_string(np, "clock-output-names", &clk_name);
	clk = xgene_register_clk_pll(NULL,
			clk_name, of_clk_get_parent_name(np, 0),
                        CLK_IS_ROOT, reg, 0, pll_type, &clk_lock);
			CLK_IS_ROOT, reg, 0, pll_type, &clk_lock,
			version);
	if (!IS_ERR(clk)) {
		of_clk_add_provider(np, of_clk_src_simple_get, clk);
		clk_register_clkdev(clk, clk_name, NULL);
@@ -518,4 +543,8 @@ static void __init xgene_devclk_init(struct device_node *np)

CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init);
CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init);
CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock",
	       xgene_socpllclk_init);
CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock",
	       xgene_pcppllclk_init);
CLK_OF_DECLARE(xgene_dev_clock, "apm,xgene-device-clock", xgene_devclk_init);