diff options
author | Tom Warren <twarren@nvidia.com> | 2015-06-25 09:50:44 -0700 |
---|---|---|
committer | Tom Warren <twarren@nvidia.com> | 2015-08-05 15:22:51 -0700 |
commit | 722e000ccd7226c5cd071590b5361620eb0b126c (patch) | |
tree | 257ddcaf4039dd6722e743e8a1f4035c2f85387f /arch/arm/mach-tegra/tegra124 | |
parent | 3e8650c0f9cc7fb29bd75c11d0173768fcc80203 (diff) | |
download | u-boot-imx-722e000ccd7226c5cd071590b5361620eb0b126c.zip u-boot-imx-722e000ccd7226c5cd071590b5361620eb0b126c.tar.gz u-boot-imx-722e000ccd7226c5cd071590b5361620eb0b126c.tar.bz2 |
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>
Diffstat (limited to 'arch/arm/mach-tegra/tegra124')
-rw-r--r-- | arch/arm/mach-tegra/tegra124/clock.c | 44 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra124/cpu.c | 31 |
2 files changed, 55 insertions, 20 deletions
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 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { }; /* + * 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 @@ void clock_early_init(void) { 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 @@ void clock_early_init(void) 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 @@ static void enable_cpu_power_rail(void) { 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_power_rail(void) 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 @@ static void remove_cpu_resets(void) 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 @@ static void remove_cpu_resets(void) } /** - * 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 @@ void tegra124_init_clocks(void) (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 @@ void tegra124_init_clocks(void) 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 @@ static void power_partition(u32 partid) 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 @@ void start_cpu(u32 reset_vector) 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__); } |