Tegra: PLL: use per-SoC pllinfo table instead of PLL_DIVM/N/P, etc.

Added PLL variables (dividers mask/shift, lock enable/detect, etc.)
to new pllinfo struct for each Soc/PLL. PLLA/C/D/E/M/P/U/X.

Used pllinfo struct in all clock functions, validated on T210.
Should be equivalent to prior code on T124/114/30/20. Thanks
to Marcel Ziswiler for corrections to the T20/T30 values.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
Signed-off-by: Tom Warren <twarren@nvidia.com>
diff --git a/arch/arm/mach-tegra/tegra124/clock.c b/arch/arm/mach-tegra/tegra124/clock.c
index b955848..9126218 100644
--- a/arch/arm/mach-tegra/tegra124/clock.c
+++ b/arch/arm/mach-tegra/tegra124/clock.c
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2013
+ * (C) Copyright 2013-2015
  * NVIDIA Corporation <www.nvidia.com>
  *
  * SPDX-License-Identifier:     GPL-2.0+
@@ -566,6 +566,36 @@
 };
 
 /*
+ * PLL divider shift/mask tables for all PLL IDs.
+ */
+struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = {
+	/*
+	 * T124: same as T114, some deviations from T2x/T30.
+	 * NOTE: If kcp_mask/kvco_mask == 0, they're not used in that PLL (PLLX, etc.)
+	 *       If lock_ena or lock_det are >31, they're not used in that PLL.
+	 */
+
+	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 20, .p_mask = 0x0F,
+	  .lock_ena = 24, .lock_det = 27, .kcp_shift = 28, .kcp_mask = 3, .kvco_shift = 27, .kvco_mask = 1 },	/* PLLC */
+	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 0,  .p_mask = 0,
+	  .lock_ena = 0,  .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLM */
+	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07,
+	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLP */
+	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07,
+	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLA */
+	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x01,
+	  .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLU */
+	{ .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07,
+	  .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLD */
+	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 20, .p_mask = 0x0F,
+	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 0, .kcp_mask = 0, .kvco_shift = 0, .kvco_mask = 0 },	/* PLLX */
+	{ .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 0,  .p_mask = 0,
+	  .lock_ena = 9,  .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },	/* PLLE */
+	{ .m_shift = 0, .m_mask = 0x0F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07,
+	  .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },	/* PLLS (RESERVED) */
+};
+
+/*
  * Get the oscillator frequency, from the corresponding hardware configuration
  * field. Note that Tegra30+ support 3 new higher freqs, but we map back
  * to the old T20 freqs. Support for the higher oscillators is TBD.
@@ -772,6 +802,8 @@
 {
 	struct clk_rst_ctlr *clkrst =
 		(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	struct clk_pll_info *pllinfo;
+	u32 data;
 
 	tegra30_set_up_pllp();
 
@@ -808,11 +840,15 @@
 	writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]);
 
 	/* PLLC_MISC: Set LOCK_ENABLE */
-	writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc);
+	pllinfo = &tegra_pll_info_table[CLOCK_ID_CGENERAL];
+	setbits_le32(&clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc, (1 << pllinfo->lock_ena));
 	udelay(2);
 
-	/* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */
-	writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc);
+	/* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1, and enable lock */
+	pllinfo = &tegra_pll_info_table[CLOCK_ID_DISPLAY];
+	data = (12 << pllinfo->kcp_shift) | (1 << pllinfo->kvco_shift);
+	data |= (1 << PLLD_CLKENABLE) | (1 << pllinfo->lock_ena);
+	writel(data, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc);
 	udelay(2);
 }
 
diff --git a/arch/arm/mach-tegra/tegra124/cpu.c b/arch/arm/mach-tegra/tegra124/cpu.c
index 974f203..0aca658 100644
--- a/arch/arm/mach-tegra/tegra124/cpu.c
+++ b/arch/arm/mach-tegra/tegra124/cpu.c
@@ -23,7 +23,7 @@
 {
 	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
 
-	debug("enable_cpu_power_rail entry\n");
+	debug("%s entry\n", __func__);
 
 	/* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */
 	pinmux_tristate_disable(PMUX_PINGRP_PWR_I2C_SCL_PZ6);
@@ -45,15 +45,16 @@
 static void enable_cpu_clocks(void)
 {
 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	struct clk_pll_info *pllinfo = &tegra_pll_info_table[CLOCK_ID_XCPU];
 	u32 reg;
 
-	debug("enable_cpu_clocks entry\n");
+	debug("%s entry\n", __func__);
 
 	/* Wait for PLL-X to lock */
 	do {
 		reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
 		debug("%s: PLLX base = 0x%08X\n", __func__, reg);
-	} while ((reg & PLL_LOCK_MASK) == 0);
+	} while ((reg & (1 << pllinfo->lock_det)) == 0);
 
 	debug("%s: PLLX locked, delay for stable clocks\n", __func__);
 	/* Wait until all clocks are stable */
@@ -83,7 +84,7 @@
 	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
 	u32 reg;
 
-	debug("remove_cpu_resets entry\n");
+	debug("%s entry\n", __func__);
 
 	/* Take the slow and fast partitions out of reset */
 	reg = CLR_NONCPURESET;
@@ -105,7 +106,7 @@
 }
 
 /**
- * The Tegra124 requires some special clock initialization, including setting up
+ * Tegra124 requires some special clock initialization, including setting up
  * the DVC I2C, turning on MSELECT and selecting the G CPU cluster
  */
 void tegra124_init_clocks(void)
@@ -116,7 +117,7 @@
 			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
 	u32 val;
 
-	debug("tegra124_init_clocks entry\n");
+	debug("%s entry\n", __func__);
 
 	/* Set active CPU cluster to G */
 	clrbits_le32(&flow->cluster_control, 1);
@@ -188,7 +189,7 @@
 	reset_set_enable(PERIPH_ID_MSELECT, 0);
 	reset_set_enable(PERIPH_ID_DVFS, 0);
 
-	debug("tegra124_init_clocks exit\n");
+	debug("%s exit\n", __func__);
 }
 
 static bool is_partition_powered(u32 partid)
@@ -223,31 +224,29 @@
 
 void powerup_cpus(void)
 {
-	debug("powerup_cpus entry\n");
-
 	/* We boot to the fast cluster */
-	debug("powerup_cpus entry: G cluster\n");
+	debug("%s entry: G cluster\n", __func__);
 
 	/* Power up the fast cluster rail partition */
-	debug("powerup_cpus: CRAIL\n");
+	debug("%s: CRAIL\n", __func__);
 	power_partition(CRAIL);
 
 	/* Power up the fast cluster non-CPU partition */
-	debug("powerup_cpus: C0NC\n");
+	debug("%s: C0NC\n", __func__);
 	power_partition(C0NC);
 
 	/* Power up the fast cluster CPU0 partition */
-	debug("powerup_cpus: CE0\n");
+	debug("%s: CE0\n", __func__);
 	power_partition(CE0);
 
-	debug("powerup_cpus: done\n");
+	debug("%s: done\n", __func__);
 }
 
 void start_cpu(u32 reset_vector)
 {
 	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
 
-	debug("start_cpu entry, reset_vector = %x\n", reset_vector);
+	debug("%s entry, reset_vector = %x\n", __func__, reset_vector);
 
 	tegra124_init_clocks();
 
@@ -261,5 +260,5 @@
 	remove_cpu_resets();
 	writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
 	powerup_cpus();
-	debug("start_cpu exit, should continue @ reset_vector\n");
+	debug("%s exit, should continue @ reset_vector\n", __func__);
 }