clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
/*
2013-04-03 17:40:36 +03:00
* Copyright ( c ) 2012 , 2013 , NVIDIA CORPORATION . All rights reserved .
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms and conditions of the GNU General Public License ,
* version 2 , as published by the Free Software Foundation .
*
* This program is distributed in the hope it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <linux/slab.h>
# include <linux/io.h>
# include <linux/delay.h>
# include <linux/err.h>
# include <linux/clk.h>
2015-06-19 15:00:46 -07:00
# include <linux/clk-provider.h>
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# include "clk.h"
# define PLL_BASE_BYPASS BIT(31)
# define PLL_BASE_ENABLE BIT(30)
# define PLL_BASE_REF_ENABLE BIT(29)
# define PLL_BASE_OVERRIDE BIT(28)
# define PLL_BASE_DIVP_SHIFT 20
# define PLL_BASE_DIVP_WIDTH 3
# define PLL_BASE_DIVN_SHIFT 8
# define PLL_BASE_DIVN_WIDTH 10
# define PLL_BASE_DIVM_SHIFT 0
# define PLL_BASE_DIVM_WIDTH 5
# define PLLU_POST_DIVP_MASK 0x1
# define PLL_MISC_DCCON_SHIFT 20
# define PLL_MISC_CPCON_SHIFT 8
# define PLL_MISC_CPCON_WIDTH 4
# define PLL_MISC_CPCON_MASK ((1 << PLL_MISC_CPCON_WIDTH) - 1)
# define PLL_MISC_LFCON_SHIFT 4
# define PLL_MISC_LFCON_WIDTH 4
# define PLL_MISC_LFCON_MASK ((1 << PLL_MISC_LFCON_WIDTH) - 1)
# define PLL_MISC_VCOCON_SHIFT 0
# define PLL_MISC_VCOCON_WIDTH 4
# define PLL_MISC_VCOCON_MASK ((1 << PLL_MISC_VCOCON_WIDTH) - 1)
# define OUT_OF_TABLE_CPCON 8
# define PMC_PLLP_WB0_OVERRIDE 0xf8
# define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12)
# define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE BIT(11)
# define PLL_POST_LOCK_DELAY 50
# define PLLDU_LFCON_SET_DIVN 600
# define PLLE_BASE_DIVCML_SHIFT 24
2014-04-04 15:55:13 +02:00
# define PLLE_BASE_DIVCML_MASK 0xf
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# define PLLE_BASE_DIVP_SHIFT 16
2014-04-04 15:55:13 +02:00
# define PLLE_BASE_DIVP_WIDTH 6
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# define PLLE_BASE_DIVN_SHIFT 8
# define PLLE_BASE_DIVN_WIDTH 8
# define PLLE_BASE_DIVM_SHIFT 0
# define PLLE_BASE_DIVM_WIDTH 8
# define PLLE_MISC_SETUP_BASE_SHIFT 16
# define PLLE_MISC_SETUP_BASE_MASK (0xffff << PLLE_MISC_SETUP_BASE_SHIFT)
# define PLLE_MISC_LOCK_ENABLE BIT(9)
# define PLLE_MISC_READY BIT(15)
# define PLLE_MISC_SETUP_EX_SHIFT 2
# define PLLE_MISC_SETUP_EX_MASK (3 << PLLE_MISC_SETUP_EX_SHIFT)
# define PLLE_MISC_SETUP_MASK (PLLE_MISC_SETUP_BASE_MASK | \
PLLE_MISC_SETUP_EX_MASK )
# define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT)
# define PLLE_SS_CTRL 0x68
2013-09-26 18:30:01 +03:00
# define PLLE_SS_CNTL_BYPASS_SS BIT(10)
# define PLLE_SS_CNTL_INTERP_RESET BIT(11)
# define PLLE_SS_CNTL_SSC_BYP BIT(12)
# define PLLE_SS_CNTL_CENTER BIT(14)
# define PLLE_SS_CNTL_INVERT BIT(15)
# define PLLE_SS_DISABLE (PLLE_SS_CNTL_BYPASS_SS | PLLE_SS_CNTL_INTERP_RESET |\
PLLE_SS_CNTL_SSC_BYP )
# define PLLE_SS_MAX_MASK 0x1ff
# define PLLE_SS_MAX_VAL 0x25
# define PLLE_SS_INC_MASK (0xff << 16)
# define PLLE_SS_INC_VAL (0x1 << 16)
# define PLLE_SS_INCINTRV_MASK (0x3f << 24)
# define PLLE_SS_INCINTRV_VAL (0x20 << 24)
# define PLLE_SS_COEFFICIENTS_MASK \
( PLLE_SS_MAX_MASK | PLLE_SS_INC_MASK | PLLE_SS_INCINTRV_MASK )
# define PLLE_SS_COEFFICIENTS_VAL \
( PLLE_SS_MAX_VAL | PLLE_SS_INC_VAL | PLLE_SS_INCINTRV_VAL )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2013-04-03 17:40:41 +03:00
# define PLLE_AUX_PLLP_SEL BIT(2)
2014-05-14 17:32:57 -07:00
# define PLLE_AUX_USE_LOCKDET BIT(3)
2013-04-03 17:40:41 +03:00
# define PLLE_AUX_ENABLE_SWCTL BIT(4)
2014-05-14 17:32:57 -07:00
# define PLLE_AUX_SS_SWCTL BIT(6)
2013-04-03 17:40:41 +03:00
# define PLLE_AUX_SEQ_ENABLE BIT(24)
2014-05-14 17:32:57 -07:00
# define PLLE_AUX_SEQ_START_STATE BIT(25)
2013-04-03 17:40:41 +03:00
# define PLLE_AUX_PLLRE_SEL BIT(28)
2014-05-14 17:32:57 -07:00
# define XUSBIO_PLL_CFG0 0x51c
# define XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0)
# define XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL BIT(2)
# define XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET BIT(6)
# define XUSBIO_PLL_CFG0_SEQ_ENABLE BIT(24)
# define XUSBIO_PLL_CFG0_SEQ_START_STATE BIT(25)
2014-06-18 17:23:23 +03:00
# define SATA_PLL_CFG0 0x490
# define SATA_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0)
2014-07-08 09:30:15 +02:00
# define SATA_PLL_CFG0_PADPLL_USE_LOCKDET BIT(2)
# define SATA_PLL_CFG0_SEQ_ENABLE BIT(24)
# define SATA_PLL_CFG0_SEQ_START_STATE BIT(25)
2014-06-18 17:23:23 +03:00
2013-04-03 17:40:41 +03:00
# define PLLE_MISC_PLLE_PTS BIT(8)
# define PLLE_MISC_IDDQ_SW_VALUE BIT(13)
# define PLLE_MISC_IDDQ_SW_CTRL BIT(14)
# define PLLE_MISC_VREG_BG_CTRL_SHIFT 4
# define PLLE_MISC_VREG_BG_CTRL_MASK (3 << PLLE_MISC_VREG_BG_CTRL_SHIFT)
# define PLLE_MISC_VREG_CTRL_SHIFT 2
# define PLLE_MISC_VREG_CTRL_MASK (2 << PLLE_MISC_VREG_CTRL_SHIFT)
# define PLLCX_MISC_STROBE BIT(31)
# define PLLCX_MISC_RESET BIT(30)
# define PLLCX_MISC_SDM_DIV_SHIFT 28
# define PLLCX_MISC_SDM_DIV_MASK (0x3 << PLLCX_MISC_SDM_DIV_SHIFT)
# define PLLCX_MISC_FILT_DIV_SHIFT 26
# define PLLCX_MISC_FILT_DIV_MASK (0x3 << PLLCX_MISC_FILT_DIV_SHIFT)
# define PLLCX_MISC_ALPHA_SHIFT 18
# define PLLCX_MISC_DIV_LOW_RANGE \
( ( 0x1 < < PLLCX_MISC_SDM_DIV_SHIFT ) | \
( 0x1 < < PLLCX_MISC_FILT_DIV_SHIFT ) )
# define PLLCX_MISC_DIV_HIGH_RANGE \
( ( 0x2 < < PLLCX_MISC_SDM_DIV_SHIFT ) | \
( 0x2 < < PLLCX_MISC_FILT_DIV_SHIFT ) )
# define PLLCX_MISC_COEF_LOW_RANGE \
( ( 0x14 < < PLLCX_MISC_KA_SHIFT ) | ( 0x38 < < PLLCX_MISC_KB_SHIFT ) )
# define PLLCX_MISC_KA_SHIFT 2
# define PLLCX_MISC_KB_SHIFT 9
# define PLLCX_MISC_DEFAULT (PLLCX_MISC_COEF_LOW_RANGE | \
( 0x19 < < PLLCX_MISC_ALPHA_SHIFT ) | \
PLLCX_MISC_DIV_LOW_RANGE | \
PLLCX_MISC_RESET )
# define PLLCX_MISC1_DEFAULT 0x000d2308
# define PLLCX_MISC2_DEFAULT 0x30211200
# define PLLCX_MISC3_DEFAULT 0x200
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# define PMC_SATA_PWRGT 0x1ac
# define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
# define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
2013-09-09 13:22:55 +03:00
# define PLLSS_MISC_KCP 0
# define PLLSS_MISC_KVCO 0
# define PLLSS_MISC_SETUP 0
# define PLLSS_EN_SDM 0
# define PLLSS_EN_SSC 0
# define PLLSS_EN_DITHER2 0
# define PLLSS_EN_DITHER 1
# define PLLSS_SDM_RESET 0
# define PLLSS_CLAMP 0
# define PLLSS_SDM_SSC_MAX 0
# define PLLSS_SDM_SSC_MIN 0
# define PLLSS_SDM_SSC_STEP 0
# define PLLSS_SDM_DIN 0
# define PLLSS_MISC_DEFAULT ((PLLSS_MISC_KCP << 25) | \
( PLLSS_MISC_KVCO < < 24 ) | \
PLLSS_MISC_SETUP )
# define PLLSS_CFG_DEFAULT ((PLLSS_EN_SDM << 31) | \
( PLLSS_EN_SSC < < 30 ) | \
( PLLSS_EN_DITHER2 < < 29 ) | \
( PLLSS_EN_DITHER < < 28 ) | \
( PLLSS_SDM_RESET ) < < 27 | \
( PLLSS_CLAMP < < 22 ) )
# define PLLSS_CTRL1_DEFAULT \
( ( PLLSS_SDM_SSC_MAX < < 16 ) | PLLSS_SDM_SSC_MIN )
# define PLLSS_CTRL2_DEFAULT \
( ( PLLSS_SDM_SSC_STEP < < 16 ) | PLLSS_SDM_DIN )
# define PLLSS_LOCK_OVERRIDE BIT(24)
# define PLLSS_REF_SRC_SEL_SHIFT 25
# define PLLSS_REF_SRC_SEL_MASK (3 << PLLSS_REF_SRC_SEL_SHIFT)
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# define pll_readl(offset, p) readl_relaxed(p->clk_base + offset)
# define pll_readl_base(p) pll_readl(p->params->base_reg, p)
# define pll_readl_misc(p) pll_readl(p->params->misc_reg, p)
2013-06-06 13:47:31 +03:00
# define pll_override_readl(offset, p) readl_relaxed(p->pmc + offset)
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset)
# define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p)
# define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p)
2013-06-06 13:47:31 +03:00
# define pll_override_writel(val, offset, p) writel(val, p->pmc + offset)
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# define mask(w) ((1 << (w)) - 1)
2013-06-05 16:51:25 +03:00
# define divm_mask(p) mask(p->params->div_nmp->divm_width)
# define divn_mask(p) mask(p->params->div_nmp->divn_width)
2013-10-04 17:28:34 +03:00
# define divp_mask(p) (p->params->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :\
2013-06-05 16:51:25 +03:00
mask ( p - > params - > div_nmp - > divp_width ) )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2014-04-04 15:55:14 +02:00
# define divm_shift(p) (p)->params->div_nmp->divm_shift
# define divn_shift(p) (p)->params->div_nmp->divn_shift
# define divp_shift(p) (p)->params->div_nmp->divp_shift
# define divm_mask_shifted(p) (divm_mask(p) << divm_shift(p))
# define divn_mask_shifted(p) (divn_mask(p) << divn_shift(p))
# define divp_mask_shifted(p) (divp_mask(p) << divp_shift(p))
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# define divm_max(p) (divm_mask(p))
# define divn_max(p) (divn_mask(p))
# define divp_max(p) (1 << (divp_mask(p)))
2013-06-05 16:51:25 +03:00
static struct div_nmp default_nmp = {
. divn_shift = PLL_BASE_DIVN_SHIFT ,
. divn_width = PLL_BASE_DIVN_WIDTH ,
. divm_shift = PLL_BASE_DIVM_SHIFT ,
. divm_width = PLL_BASE_DIVM_WIDTH ,
. divp_shift = PLL_BASE_DIVP_SHIFT ,
. divp_width = PLL_BASE_DIVP_WIDTH ,
} ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
static void clk_pll_enable_lock ( struct tegra_clk_pll * pll )
{
u32 val ;
2013-10-04 17:28:34 +03:00
if ( ! ( pll - > params - > flags & TEGRA_PLL_USE_LOCK ) )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return ;
2013-10-04 17:28:34 +03:00
if ( ! ( pll - > params - > flags & TEGRA_PLL_HAS_LOCK_ENABLE ) )
2013-04-03 17:40:38 +03:00
return ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
val = pll_readl_misc ( pll ) ;
val | = BIT ( pll - > params - > lock_enable_bit_idx ) ;
pll_writel_misc ( val , pll ) ;
}
2013-04-03 17:40:36 +03:00
static int clk_pll_wait_for_lock ( struct tegra_clk_pll * pll )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
{
int i ;
2013-04-03 17:40:40 +03:00
u32 val , lock_mask ;
2013-04-03 17:40:36 +03:00
void __iomem * lock_addr ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2013-10-04 17:28:34 +03:00
if ( ! ( pll - > params - > flags & TEGRA_PLL_USE_LOCK ) ) {
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
udelay ( pll - > params - > lock_delay ) ;
return 0 ;
}
2013-04-03 17:40:36 +03:00
lock_addr = pll - > clk_base ;
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLL_LOCK_MISC )
2013-04-03 17:40:36 +03:00
lock_addr + = pll - > params - > misc_reg ;
else
lock_addr + = pll - > params - > base_reg ;
2013-04-03 17:40:40 +03:00
lock_mask = pll - > params - > lock_mask ;
2013-04-03 17:40:36 +03:00
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
for ( i = 0 ; i < pll - > params - > lock_delay ; i + + ) {
val = readl_relaxed ( lock_addr ) ;
2013-04-03 17:40:40 +03:00
if ( ( val & lock_mask ) = = lock_mask ) {
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
udelay ( PLL_POST_LOCK_DELAY ) ;
return 0 ;
}
udelay ( 2 ) ; /* timeout = 2 * lock time */
}
pr_err ( " %s: Timed out waiting for pll %s lock \n " , __func__ ,
2015-08-12 11:42:23 -07:00
clk_hw_get_name ( & pll - > hw ) ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return - 1 ;
}
2015-06-18 17:28:19 -04:00
int tegra_pll_wait_for_lock ( struct tegra_clk_pll * pll )
{
return clk_pll_wait_for_lock ( pll ) ;
}
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
static int clk_pll_is_enabled ( struct clk_hw * hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
u32 val ;
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLLM ) {
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
val = readl_relaxed ( pll - > pmc + PMC_PLLP_WB0_OVERRIDE ) ;
if ( val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE )
return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0 ;
}
val = pll_readl_base ( pll ) ;
return val & PLL_BASE_ENABLE ? 1 : 0 ;
}
2013-04-03 17:40:36 +03:00
static void _clk_pll_enable ( struct clk_hw * hw )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
u32 val ;
2015-06-18 17:28:20 -04:00
if ( pll - > params - > iddq_reg ) {
val = pll_readl ( pll - > params - > iddq_reg , pll ) ;
val & = ~ BIT ( pll - > params - > iddq_bit_idx ) ;
pll_writel ( val , pll - > params - > iddq_reg , pll ) ;
udelay ( 2 ) ;
}
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
clk_pll_enable_lock ( pll ) ;
val = pll_readl_base ( pll ) ;
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLL_BYPASS )
2013-04-03 17:40:37 +03:00
val & = ~ PLL_BASE_BYPASS ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
val | = PLL_BASE_ENABLE ;
pll_writel_base ( val , pll ) ;
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLLM ) {
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
val = readl_relaxed ( pll - > pmc + PMC_PLLP_WB0_OVERRIDE ) ;
val | = PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ;
writel_relaxed ( val , pll - > pmc + PMC_PLLP_WB0_OVERRIDE ) ;
}
}
static void _clk_pll_disable ( struct clk_hw * hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
u32 val ;
val = pll_readl_base ( pll ) ;
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLL_BYPASS )
2013-04-03 17:40:37 +03:00
val & = ~ PLL_BASE_BYPASS ;
val & = ~ PLL_BASE_ENABLE ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
pll_writel_base ( val , pll ) ;
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLLM ) {
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
val = readl_relaxed ( pll - > pmc + PMC_PLLP_WB0_OVERRIDE ) ;
val & = ~ PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ;
writel_relaxed ( val , pll - > pmc + PMC_PLLP_WB0_OVERRIDE ) ;
}
2015-06-18 17:28:20 -04:00
if ( pll - > params - > iddq_reg ) {
val = pll_readl ( pll - > params - > iddq_reg , pll ) ;
val | = BIT ( pll - > params - > iddq_bit_idx ) ;
pll_writel ( val , pll - > params - > iddq_reg , pll ) ;
udelay ( 2 ) ;
}
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
}
static int clk_pll_enable ( struct clk_hw * hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
unsigned long flags = 0 ;
int ret ;
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
2013-04-03 17:40:36 +03:00
_clk_pll_enable ( hw ) ;
ret = clk_pll_wait_for_lock ( pll ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
return ret ;
}
static void clk_pll_disable ( struct clk_hw * hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
unsigned long flags = 0 ;
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
_clk_pll_disable ( hw ) ;
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
}
2013-06-05 15:56:41 +03:00
static int _p_div_to_hw ( struct clk_hw * hw , u8 p_div )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
2015-11-19 16:34:06 +01:00
const struct pdiv_map * p_tohw = pll - > params - > pdiv_tohw ;
2013-06-05 15:56:41 +03:00
if ( p_tohw ) {
while ( p_tohw - > pdiv ) {
if ( p_div < = p_tohw - > pdiv )
return p_tohw - > hw_val ;
p_tohw + + ;
}
return - EINVAL ;
}
return - EINVAL ;
}
static int _hw_to_p_div ( struct clk_hw * hw , u8 p_div_hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
2015-11-19 16:34:06 +01:00
const struct pdiv_map * p_tohw = pll - > params - > pdiv_tohw ;
2013-06-05 15:56:41 +03:00
if ( p_tohw ) {
while ( p_tohw - > pdiv ) {
if ( p_div_hw = = p_tohw - > hw_val )
return p_tohw - > pdiv ;
p_tohw + + ;
}
return - EINVAL ;
}
return 1 < < p_div_hw ;
}
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
static int _get_table_rate ( struct clk_hw * hw ,
struct tegra_clk_pll_freq_table * cfg ,
unsigned long rate , unsigned long parent_rate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
struct tegra_clk_pll_freq_table * sel ;
2013-10-04 17:28:34 +03:00
for ( sel = pll - > params - > freq_table ; sel - > input_rate ! = 0 ; sel + + )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
if ( sel - > input_rate = = parent_rate & &
sel - > output_rate = = rate )
break ;
if ( sel - > input_rate = = 0 )
return - EINVAL ;
cfg - > input_rate = sel - > input_rate ;
cfg - > output_rate = sel - > output_rate ;
cfg - > m = sel - > m ;
cfg - > n = sel - > n ;
cfg - > p = sel - > p ;
cfg - > cpcon = sel - > cpcon ;
return 0 ;
}
static int _calc_rate ( struct clk_hw * hw , struct tegra_clk_pll_freq_table * cfg ,
unsigned long rate , unsigned long parent_rate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
unsigned long cfreq ;
u32 p_div = 0 ;
2013-06-05 15:56:41 +03:00
int ret ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
switch ( parent_rate ) {
case 12000000 :
case 26000000 :
cfreq = ( rate < = 1000000 * 1000 ) ? 1000000 : 2000000 ;
break ;
case 13000000 :
cfreq = ( rate < = 1000000 * 1000 ) ? 1000000 : 2600000 ;
break ;
case 16800000 :
case 19200000 :
cfreq = ( rate < = 1200000 * 1000 ) ? 1200000 : 2400000 ;
break ;
case 9600000 :
case 28800000 :
/*
* PLL_P_OUT1 rate is not listed in PLLA table
*/
2015-11-18 14:04:20 +01:00
cfreq = parent_rate / ( parent_rate / 1000000 ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
break ;
default :
pr_err ( " %s Unexpected reference rate %lu \n " ,
__func__ , parent_rate ) ;
BUG ( ) ;
}
/* Raise VCO to guarantee 0.5% accuracy */
for ( cfg - > output_rate = rate ; cfg - > output_rate < 200 * cfreq ;
cfg - > output_rate < < = 1 )
p_div + + ;
cfg - > m = parent_rate / cfreq ;
cfg - > n = cfg - > output_rate / cfreq ;
cfg - > cpcon = OUT_OF_TABLE_CPCON ;
if ( cfg - > m > divm_max ( pll ) | | cfg - > n > divn_max ( pll ) | |
2013-04-03 17:40:36 +03:00
( 1 < < p_div ) > divp_max ( pll )
| | cfg - > output_rate > pll - > params - > vco_max ) {
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return - EINVAL ;
}
2013-11-18 16:11:35 +01:00
cfg - > output_rate > > = p_div ;
2013-06-05 15:56:41 +03:00
if ( pll - > params - > pdiv_tohw ) {
ret = _p_div_to_hw ( hw , 1 < < p_div ) ;
if ( ret < 0 )
return ret ;
else
cfg - > p = ret ;
2013-04-03 17:40:39 +03:00
} else
cfg - > p = p_div ;
2013-04-03 17:40:36 +03:00
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return 0 ;
}
2013-04-03 17:40:36 +03:00
static void _update_pll_mnp ( struct tegra_clk_pll * pll ,
struct tegra_clk_pll_freq_table * cfg )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
{
2013-04-03 17:40:36 +03:00
u32 val ;
2013-06-06 13:47:31 +03:00
struct tegra_clk_pll_params * params = pll - > params ;
struct div_nmp * div_nmp = params - > div_nmp ;
2013-10-04 17:28:34 +03:00
if ( ( params - > flags & TEGRA_PLLM ) & &
2013-06-06 13:47:31 +03:00
( pll_override_readl ( PMC_PLLP_WB0_OVERRIDE , pll ) &
PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE ) ) {
val = pll_override_readl ( params - > pmc_divp_reg , pll ) ;
val & = ~ ( divp_mask ( pll ) < < div_nmp - > override_divp_shift ) ;
val | = cfg - > p < < div_nmp - > override_divp_shift ;
pll_override_writel ( val , params - > pmc_divp_reg , pll ) ;
val = pll_override_readl ( params - > pmc_divnm_reg , pll ) ;
val & = ~ ( divm_mask ( pll ) < < div_nmp - > override_divm_shift ) |
~ ( divn_mask ( pll ) < < div_nmp - > override_divn_shift ) ;
val | = ( cfg - > m < < div_nmp - > override_divm_shift ) |
( cfg - > n < < div_nmp - > override_divn_shift ) ;
pll_override_writel ( val , params - > pmc_divnm_reg , pll ) ;
} else {
val = pll_readl_base ( pll ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2014-04-04 15:55:14 +02:00
val & = ~ ( divm_mask_shifted ( pll ) | divn_mask_shifted ( pll ) |
divp_mask_shifted ( pll ) ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2014-04-04 15:55:14 +02:00
val | = ( cfg - > m < < divm_shift ( pll ) ) |
( cfg - > n < < divn_shift ( pll ) ) |
( cfg - > p < < divp_shift ( pll ) ) ;
2013-04-03 17:40:36 +03:00
2013-06-06 13:47:31 +03:00
pll_writel_base ( val , pll ) ;
}
2013-04-03 17:40:36 +03:00
}
static void _get_pll_mnp ( struct tegra_clk_pll * pll ,
struct tegra_clk_pll_freq_table * cfg )
{
u32 val ;
2013-06-06 13:47:31 +03:00
struct tegra_clk_pll_params * params = pll - > params ;
struct div_nmp * div_nmp = params - > div_nmp ;
2013-10-04 17:28:34 +03:00
if ( ( params - > flags & TEGRA_PLLM ) & &
2013-06-06 13:47:31 +03:00
( pll_override_readl ( PMC_PLLP_WB0_OVERRIDE , pll ) &
PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE ) ) {
val = pll_override_readl ( params - > pmc_divp_reg , pll ) ;
cfg - > p = ( val > > div_nmp - > override_divp_shift ) & divp_mask ( pll ) ;
val = pll_override_readl ( params - > pmc_divnm_reg , pll ) ;
cfg - > m = ( val > > div_nmp - > override_divm_shift ) & divm_mask ( pll ) ;
cfg - > n = ( val > > div_nmp - > override_divn_shift ) & divn_mask ( pll ) ;
} else {
val = pll_readl_base ( pll ) ;
2013-04-03 17:40:36 +03:00
2013-06-06 13:47:31 +03:00
cfg - > m = ( val > > div_nmp - > divm_shift ) & divm_mask ( pll ) ;
cfg - > n = ( val > > div_nmp - > divn_shift ) & divn_mask ( pll ) ;
cfg - > p = ( val > > div_nmp - > divp_shift ) & divp_mask ( pll ) ;
}
2013-04-03 17:40:36 +03:00
}
static void _update_pll_cpcon ( struct tegra_clk_pll * pll ,
struct tegra_clk_pll_freq_table * cfg ,
unsigned long rate )
{
u32 val ;
val = pll_readl_misc ( pll ) ;
val & = ~ ( PLL_MISC_CPCON_MASK < < PLL_MISC_CPCON_SHIFT ) ;
val | = cfg - > cpcon < < PLL_MISC_CPCON_SHIFT ;
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLL_SET_LFCON ) {
2013-04-03 17:40:36 +03:00
val & = ~ ( PLL_MISC_LFCON_MASK < < PLL_MISC_LFCON_SHIFT ) ;
if ( cfg - > n > = PLLDU_LFCON_SET_DIVN )
val | = 1 < < PLL_MISC_LFCON_SHIFT ;
2013-10-04 17:28:34 +03:00
} else if ( pll - > params - > flags & TEGRA_PLL_SET_DCCON ) {
2013-04-03 17:40:36 +03:00
val & = ~ ( 1 < < PLL_MISC_DCCON_SHIFT ) ;
if ( rate > = ( pll - > params - > vco_max > > 1 ) )
val | = 1 < < PLL_MISC_DCCON_SHIFT ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
}
2013-04-03 17:40:36 +03:00
pll_writel_misc ( val , pll ) ;
}
static int _program_pll ( struct clk_hw * hw , struct tegra_clk_pll_freq_table * cfg ,
unsigned long rate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
int state , ret = 0 ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
state = clk_pll_is_enabled ( hw ) ;
2013-04-03 17:40:36 +03:00
if ( state )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
_clk_pll_disable ( hw ) ;
2013-04-03 17:40:36 +03:00
_update_pll_mnp ( pll , cfg ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLL_HAS_CPCON )
2013-04-03 17:40:36 +03:00
_update_pll_cpcon ( pll , cfg , rate ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2013-04-03 17:40:36 +03:00
if ( state ) {
_clk_pll_enable ( hw ) ;
ret = clk_pll_wait_for_lock ( pll ) ;
}
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2013-04-03 17:40:36 +03:00
return ret ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
}
static int clk_pll_set_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long parent_rate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
2013-04-03 17:40:36 +03:00
struct tegra_clk_pll_freq_table cfg , old_cfg ;
unsigned long flags = 0 ;
int ret = 0 ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLL_FIXED ) {
if ( rate ! = pll - > params - > fixed_rate ) {
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
pr_err ( " %s: Can not change %s fixed rate %lu to %lu \n " ,
2015-08-12 11:42:23 -07:00
__func__ , clk_hw_get_name ( hw ) ,
2013-10-04 17:28:34 +03:00
pll - > params - > fixed_rate , rate ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return - EINVAL ;
}
return 0 ;
}
if ( _get_table_rate ( hw , & cfg , rate , parent_rate ) & &
2013-06-05 15:56:41 +03:00
_calc_rate ( hw , & cfg , rate , parent_rate ) ) {
2013-11-27 17:26:03 +01:00
pr_err ( " %s: Failed to set %s rate %lu \n " , __func__ ,
2015-08-12 11:42:23 -07:00
clk_hw_get_name ( hw ) , rate ) ;
2013-06-05 15:56:41 +03:00
WARN_ON ( 1 ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return - EINVAL ;
2013-06-05 15:56:41 +03:00
}
2013-04-03 17:40:36 +03:00
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
_get_pll_mnp ( pll , & old_cfg ) ;
if ( old_cfg . m ! = cfg . m | | old_cfg . n ! = cfg . n | | old_cfg . p ! = cfg . p )
ret = _program_pll ( hw , & cfg , rate ) ;
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
return ret ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
}
static long clk_pll_round_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long * prate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
struct tegra_clk_pll_freq_table cfg ;
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLL_FIXED )
return pll - > params - > fixed_rate ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
/* PLLM is used for memory; we do not change rate */
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLLM )
2015-07-30 17:20:57 -07:00
return clk_hw_get_rate ( hw ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
if ( _get_table_rate ( hw , & cfg , rate , * prate ) & &
2013-11-27 17:26:03 +01:00
_calc_rate ( hw , & cfg , rate , * prate ) )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return - EINVAL ;
2013-06-05 15:56:41 +03:00
return cfg . output_rate ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
}
static unsigned long clk_pll_recalc_rate ( struct clk_hw * hw ,
unsigned long parent_rate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
2013-04-03 17:40:36 +03:00
struct tegra_clk_pll_freq_table cfg ;
u32 val ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
u64 rate = parent_rate ;
2013-04-03 17:40:39 +03:00
int pdiv ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2013-04-03 17:40:36 +03:00
val = pll_readl_base ( pll ) ;
2013-10-04 17:28:34 +03:00
if ( ( pll - > params - > flags & TEGRA_PLL_BYPASS ) & & ( val & PLL_BASE_BYPASS ) )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return parent_rate ;
2013-10-04 17:28:34 +03:00
if ( ( pll - > params - > flags & TEGRA_PLL_FIXED ) & &
! ( val & PLL_BASE_OVERRIDE ) ) {
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
struct tegra_clk_pll_freq_table sel ;
2013-10-04 17:28:34 +03:00
if ( _get_table_rate ( hw , & sel , pll - > params - > fixed_rate ,
parent_rate ) ) {
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
pr_err ( " Clock %s has unknown fixed frequency \n " ,
2015-08-12 11:42:23 -07:00
clk_hw_get_name ( hw ) ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
BUG ( ) ;
}
2013-10-04 17:28:34 +03:00
return pll - > params - > fixed_rate ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
}
2013-04-03 17:40:36 +03:00
_get_pll_mnp ( pll , & cfg ) ;
2013-06-05 15:56:41 +03:00
pdiv = _hw_to_p_div ( hw , cfg . p ) ;
if ( pdiv < 0 ) {
2015-06-18 17:28:21 -04:00
WARN ( 1 , " Clock %s has invalid pdiv value : 0x%x \n " ,
__clk_get_name ( hw - > clk ) , cfg . p ) ;
2013-06-05 15:56:41 +03:00
pdiv = 1 ;
}
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2013-04-03 17:40:39 +03:00
cfg . m * = pdiv ;
2013-04-03 17:40:36 +03:00
rate * = cfg . n ;
do_div ( rate , cfg . m ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return rate ;
}
static int clk_plle_training ( struct tegra_clk_pll * pll )
{
u32 val ;
unsigned long timeout ;
if ( ! pll - > pmc )
return - ENOSYS ;
/*
* PLLE is already disabled , and setup cleared ;
* create falling edge on PLLE IDDQ input .
*/
val = readl ( pll - > pmc + PMC_SATA_PWRGT ) ;
val | = PMC_SATA_PWRGT_PLLE_IDDQ_VALUE ;
writel ( val , pll - > pmc + PMC_SATA_PWRGT ) ;
val = readl ( pll - > pmc + PMC_SATA_PWRGT ) ;
val | = PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL ;
writel ( val , pll - > pmc + PMC_SATA_PWRGT ) ;
val = readl ( pll - > pmc + PMC_SATA_PWRGT ) ;
val & = ~ PMC_SATA_PWRGT_PLLE_IDDQ_VALUE ;
writel ( val , pll - > pmc + PMC_SATA_PWRGT ) ;
val = pll_readl_misc ( pll ) ;
timeout = jiffies + msecs_to_jiffies ( 100 ) ;
while ( 1 ) {
val = pll_readl_misc ( pll ) ;
if ( val & PLLE_MISC_READY )
break ;
if ( time_after ( jiffies , timeout ) ) {
pr_err ( " %s: timeout waiting for PLLE \n " , __func__ ) ;
return - EBUSY ;
}
udelay ( 300 ) ;
}
return 0 ;
}
static int clk_plle_enable ( struct clk_hw * hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
unsigned long input_rate = clk_get_rate ( clk_get_parent ( hw - > clk ) ) ;
struct tegra_clk_pll_freq_table sel ;
u32 val ;
int err ;
2013-10-04 17:28:34 +03:00
if ( _get_table_rate ( hw , & sel , pll - > params - > fixed_rate , input_rate ) )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return - EINVAL ;
clk_pll_disable ( hw ) ;
val = pll_readl_misc ( pll ) ;
val & = ~ ( PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK ) ;
pll_writel_misc ( val , pll ) ;
val = pll_readl_misc ( pll ) ;
if ( ! ( val & PLLE_MISC_READY ) ) {
err = clk_plle_training ( pll ) ;
if ( err )
return err ;
}
2013-10-04 17:28:34 +03:00
if ( pll - > params - > flags & TEGRA_PLLE_CONFIGURE ) {
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
/* configure dividers */
val = pll_readl_base ( pll ) ;
2014-04-04 15:55:14 +02:00
val & = ~ ( divp_mask_shifted ( pll ) | divn_mask_shifted ( pll ) |
divm_mask_shifted ( pll ) ) ;
2014-04-04 15:55:13 +02:00
val & = ~ ( PLLE_BASE_DIVCML_MASK < < PLLE_BASE_DIVCML_SHIFT ) ;
2014-04-04 15:55:14 +02:00
val | = sel . m < < divm_shift ( pll ) ;
val | = sel . n < < divn_shift ( pll ) ;
val | = sel . p < < divp_shift ( pll ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
val | = sel . cpcon < < PLLE_BASE_DIVCML_SHIFT ;
pll_writel_base ( val , pll ) ;
}
val = pll_readl_misc ( pll ) ;
val | = PLLE_MISC_SETUP_VALUE ;
val | = PLLE_MISC_LOCK_ENABLE ;
pll_writel_misc ( val , pll ) ;
val = readl ( pll - > clk_base + PLLE_SS_CTRL ) ;
2014-04-04 15:55:13 +02:00
val & = ~ PLLE_SS_COEFFICIENTS_MASK ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
val | = PLLE_SS_DISABLE ;
writel ( val , pll - > clk_base + PLLE_SS_CTRL ) ;
2014-04-04 15:55:15 +02:00
val = pll_readl_base ( pll ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
val | = ( PLL_BASE_BYPASS | PLL_BASE_ENABLE ) ;
pll_writel_base ( val , pll ) ;
2013-04-03 17:40:36 +03:00
clk_pll_wait_for_lock ( pll ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
return 0 ;
}
static unsigned long clk_plle_recalc_rate ( struct clk_hw * hw ,
unsigned long parent_rate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
u32 val = pll_readl_base ( pll ) ;
u32 divn = 0 , divm = 0 , divp = 0 ;
u64 rate = parent_rate ;
2013-06-05 16:51:25 +03:00
divp = ( val > > pll - > params - > div_nmp - > divp_shift ) & ( divp_mask ( pll ) ) ;
divn = ( val > > pll - > params - > div_nmp - > divn_shift ) & ( divn_mask ( pll ) ) ;
divm = ( val > > pll - > params - > div_nmp - > divm_shift ) & ( divm_mask ( pll ) ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
divm * = divp ;
rate * = divn ;
do_div ( rate , divm ) ;
return rate ;
}
const struct clk_ops tegra_clk_pll_ops = {
. is_enabled = clk_pll_is_enabled ,
. enable = clk_pll_enable ,
. disable = clk_pll_disable ,
. recalc_rate = clk_pll_recalc_rate ,
. round_rate = clk_pll_round_rate ,
. set_rate = clk_pll_set_rate ,
} ;
const struct clk_ops tegra_clk_plle_ops = {
. recalc_rate = clk_plle_recalc_rate ,
. is_enabled = clk_pll_is_enabled ,
. disable = clk_pll_disable ,
. enable = clk_plle_enable ,
} ;
2014-12-16 12:38:29 -08:00
# if defined(CONFIG_ARCH_TEGRA_114_SOC) || \
defined ( CONFIG_ARCH_TEGRA_124_SOC ) | | \
defined ( CONFIG_ARCH_TEGRA_132_SOC )
2013-04-03 17:40:41 +03:00
static int _pll_fixed_mdiv ( struct tegra_clk_pll_params * pll_params ,
unsigned long parent_rate )
{
if ( parent_rate > pll_params - > cf_max )
return 2 ;
else
return 1 ;
}
2013-09-06 14:37:37 +03:00
static unsigned long _clip_vco_min ( unsigned long vco_min ,
unsigned long parent_rate )
{
return DIV_ROUND_UP ( vco_min , parent_rate ) * parent_rate ;
}
static int _setup_dynamic_ramp ( struct tegra_clk_pll_params * pll_params ,
void __iomem * clk_base ,
unsigned long parent_rate )
{
u32 val ;
u32 step_a , step_b ;
switch ( parent_rate ) {
case 12000000 :
case 13000000 :
case 26000000 :
step_a = 0x2B ;
step_b = 0x0B ;
break ;
case 16800000 :
step_a = 0x1A ;
step_b = 0x09 ;
break ;
case 19200000 :
step_a = 0x12 ;
step_b = 0x08 ;
break ;
default :
pr_err ( " %s: Unexpected reference rate %lu \n " ,
__func__ , parent_rate ) ;
WARN_ON ( 1 ) ;
return - EINVAL ;
}
val = step_a < < pll_params - > stepa_shift ;
val | = step_b < < pll_params - > stepb_shift ;
writel_relaxed ( val , clk_base + pll_params - > dyn_ramp_reg ) ;
return 0 ;
}
2013-04-03 17:40:41 +03:00
static int _calc_dynamic_ramp_rate ( struct clk_hw * hw ,
struct tegra_clk_pll_freq_table * cfg ,
unsigned long rate , unsigned long parent_rate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
unsigned int p ;
2013-06-05 15:56:41 +03:00
int p_div ;
2013-04-03 17:40:41 +03:00
if ( ! rate )
return - EINVAL ;
p = DIV_ROUND_UP ( pll - > params - > vco_min , rate ) ;
cfg - > m = _pll_fixed_mdiv ( pll - > params , parent_rate ) ;
2013-06-05 15:56:41 +03:00
cfg - > output_rate = rate * p ;
2013-04-03 17:40:41 +03:00
cfg - > n = cfg - > output_rate * cfg - > m / parent_rate ;
2013-06-05 15:56:41 +03:00
p_div = _p_div_to_hw ( hw , p ) ;
if ( p_div < 0 )
return p_div ;
2015-11-18 14:04:20 +01:00
cfg - > p = p_div ;
2013-06-05 15:56:41 +03:00
2013-04-03 17:40:41 +03:00
if ( cfg - > n > divn_max ( pll ) | | cfg - > output_rate > pll - > params - > vco_max )
return - EINVAL ;
return 0 ;
}
static int _pll_ramp_calc_pll ( struct clk_hw * hw ,
struct tegra_clk_pll_freq_table * cfg ,
unsigned long rate , unsigned long parent_rate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
2013-06-05 15:56:41 +03:00
int err = 0 , p_div ;
2013-04-03 17:40:41 +03:00
err = _get_table_rate ( hw , cfg , rate , parent_rate ) ;
if ( err < 0 )
err = _calc_dynamic_ramp_rate ( hw , cfg , rate , parent_rate ) ;
2013-06-05 15:56:41 +03:00
else {
if ( cfg - > m ! = _pll_fixed_mdiv ( pll - > params , parent_rate ) ) {
2013-04-03 17:40:41 +03:00
WARN_ON ( 1 ) ;
err = - EINVAL ;
goto out ;
2013-06-05 15:56:41 +03:00
}
p_div = _p_div_to_hw ( hw , cfg - > p ) ;
if ( p_div < 0 )
return p_div ;
else
cfg - > p = p_div ;
2013-04-03 17:40:41 +03:00
}
2013-06-05 15:56:41 +03:00
if ( cfg - > p > pll - > params - > max_p )
2013-04-03 17:40:41 +03:00
err = - EINVAL ;
out :
return err ;
}
static int clk_pllxc_set_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long parent_rate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
struct tegra_clk_pll_freq_table cfg , old_cfg ;
unsigned long flags = 0 ;
2015-02-18 16:25:16 +01:00
int ret ;
2013-04-03 17:40:41 +03:00
ret = _pll_ramp_calc_pll ( hw , & cfg , rate , parent_rate ) ;
if ( ret < 0 )
return ret ;
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
_get_pll_mnp ( pll , & old_cfg ) ;
2013-06-05 15:56:41 +03:00
if ( old_cfg . m ! = cfg . m | | old_cfg . n ! = cfg . n | | old_cfg . p ! = cfg . p )
2013-04-03 17:40:41 +03:00
ret = _program_pll ( hw , & cfg , rate ) ;
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
return ret ;
}
static long clk_pll_ramp_round_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long * prate )
{
struct tegra_clk_pll_freq_table cfg ;
2015-02-18 16:25:16 +01:00
int ret , p_div ;
2013-04-03 17:40:41 +03:00
u64 output_rate = * prate ;
ret = _pll_ramp_calc_pll ( hw , & cfg , rate , * prate ) ;
if ( ret < 0 )
return ret ;
2013-06-05 15:56:41 +03:00
p_div = _hw_to_p_div ( hw , cfg . p ) ;
if ( p_div < 0 )
return p_div ;
2013-04-03 17:40:41 +03:00
output_rate * = cfg . n ;
2013-06-05 15:56:41 +03:00
do_div ( output_rate , cfg . m * p_div ) ;
2013-04-03 17:40:41 +03:00
return output_rate ;
}
static int clk_pllm_set_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long parent_rate )
{
struct tegra_clk_pll_freq_table cfg ;
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
unsigned long flags = 0 ;
int state , ret = 0 ;
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
state = clk_pll_is_enabled ( hw ) ;
if ( state ) {
if ( rate ! = clk_get_rate ( hw - > clk ) ) {
pr_err ( " %s: Cannot change active PLLM \n " , __func__ ) ;
ret = - EINVAL ;
goto out ;
}
goto out ;
}
ret = _pll_ramp_calc_pll ( hw , & cfg , rate , parent_rate ) ;
if ( ret < 0 )
goto out ;
2013-06-06 13:47:31 +03:00
_update_pll_mnp ( pll , & cfg ) ;
2013-04-03 17:40:41 +03:00
out :
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
return ret ;
}
static void _pllcx_strobe ( struct tegra_clk_pll * pll )
{
u32 val ;
val = pll_readl_misc ( pll ) ;
val | = PLLCX_MISC_STROBE ;
pll_writel_misc ( val , pll ) ;
udelay ( 2 ) ;
val & = ~ PLLCX_MISC_STROBE ;
pll_writel_misc ( val , pll ) ;
}
static int clk_pllc_enable ( struct clk_hw * hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
u32 val ;
2015-02-18 16:25:16 +01:00
int ret ;
2013-04-03 17:40:41 +03:00
unsigned long flags = 0 ;
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
_clk_pll_enable ( hw ) ;
udelay ( 2 ) ;
val = pll_readl_misc ( pll ) ;
val & = ~ PLLCX_MISC_RESET ;
pll_writel_misc ( val , pll ) ;
udelay ( 2 ) ;
_pllcx_strobe ( pll ) ;
ret = clk_pll_wait_for_lock ( pll ) ;
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
return ret ;
}
static void _clk_pllc_disable ( struct clk_hw * hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
u32 val ;
_clk_pll_disable ( hw ) ;
val = pll_readl_misc ( pll ) ;
val | = PLLCX_MISC_RESET ;
pll_writel_misc ( val , pll ) ;
udelay ( 2 ) ;
}
static void clk_pllc_disable ( struct clk_hw * hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
unsigned long flags = 0 ;
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
_clk_pllc_disable ( hw ) ;
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
}
static int _pllcx_update_dynamic_coef ( struct tegra_clk_pll * pll ,
unsigned long input_rate , u32 n )
{
u32 val , n_threshold ;
switch ( input_rate ) {
case 12000000 :
n_threshold = 70 ;
break ;
case 13000000 :
case 26000000 :
n_threshold = 71 ;
break ;
case 16800000 :
n_threshold = 55 ;
break ;
case 19200000 :
n_threshold = 48 ;
break ;
default :
pr_err ( " %s: Unexpected reference rate %lu \n " ,
__func__ , input_rate ) ;
return - EINVAL ;
}
val = pll_readl_misc ( pll ) ;
val & = ~ ( PLLCX_MISC_SDM_DIV_MASK | PLLCX_MISC_FILT_DIV_MASK ) ;
val | = n < = n_threshold ?
PLLCX_MISC_DIV_LOW_RANGE : PLLCX_MISC_DIV_HIGH_RANGE ;
pll_writel_misc ( val , pll ) ;
return 0 ;
}
static int clk_pllc_set_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long parent_rate )
{
2013-06-05 15:56:41 +03:00
struct tegra_clk_pll_freq_table cfg , old_cfg ;
2013-04-03 17:40:41 +03:00
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
unsigned long flags = 0 ;
int state , ret = 0 ;
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
ret = _pll_ramp_calc_pll ( hw , & cfg , rate , parent_rate ) ;
if ( ret < 0 )
goto out ;
2013-06-05 15:56:41 +03:00
_get_pll_mnp ( pll , & old_cfg ) ;
2013-04-03 17:40:41 +03:00
2013-06-05 15:56:41 +03:00
if ( cfg . m ! = old_cfg . m ) {
2013-04-03 17:40:41 +03:00
WARN_ON ( 1 ) ;
goto out ;
}
2013-06-05 15:56:41 +03:00
if ( old_cfg . n = = cfg . n & & old_cfg . p = = cfg . p )
2013-04-03 17:40:41 +03:00
goto out ;
state = clk_pll_is_enabled ( hw ) ;
if ( state )
_clk_pllc_disable ( hw ) ;
ret = _pllcx_update_dynamic_coef ( pll , parent_rate , cfg . n ) ;
if ( ret < 0 )
goto out ;
_update_pll_mnp ( pll , & cfg ) ;
if ( state )
ret = clk_pllc_enable ( hw ) ;
out :
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
return ret ;
}
static long _pllre_calc_rate ( struct tegra_clk_pll * pll ,
struct tegra_clk_pll_freq_table * cfg ,
unsigned long rate , unsigned long parent_rate )
{
u16 m , n ;
u64 output_rate = parent_rate ;
m = _pll_fixed_mdiv ( pll - > params , parent_rate ) ;
n = rate * m / parent_rate ;
output_rate * = n ;
do_div ( output_rate , m ) ;
if ( cfg ) {
cfg - > m = m ;
cfg - > n = n ;
}
return output_rate ;
}
2014-08-01 10:44:20 +02:00
2013-04-03 17:40:41 +03:00
static int clk_pllre_set_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long parent_rate )
{
struct tegra_clk_pll_freq_table cfg , old_cfg ;
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
unsigned long flags = 0 ;
int state , ret = 0 ;
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
_pllre_calc_rate ( pll , & cfg , rate , parent_rate ) ;
_get_pll_mnp ( pll , & old_cfg ) ;
cfg . p = old_cfg . p ;
if ( cfg . m ! = old_cfg . m | | cfg . n ! = old_cfg . n ) {
state = clk_pll_is_enabled ( hw ) ;
if ( state )
_clk_pll_disable ( hw ) ;
_update_pll_mnp ( pll , & cfg ) ;
if ( state ) {
_clk_pll_enable ( hw ) ;
ret = clk_pll_wait_for_lock ( pll ) ;
}
}
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
return ret ;
}
static unsigned long clk_pllre_recalc_rate ( struct clk_hw * hw ,
unsigned long parent_rate )
{
struct tegra_clk_pll_freq_table cfg ;
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
u64 rate = parent_rate ;
_get_pll_mnp ( pll , & cfg ) ;
rate * = cfg . n ;
do_div ( rate , cfg . m ) ;
return rate ;
}
static long clk_pllre_round_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long * prate )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
return _pllre_calc_rate ( pll , NULL , rate , * prate ) ;
}
static int clk_plle_tegra114_enable ( struct clk_hw * hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
struct tegra_clk_pll_freq_table sel ;
u32 val ;
int ret ;
unsigned long flags = 0 ;
unsigned long input_rate = clk_get_rate ( clk_get_parent ( hw - > clk ) ) ;
2013-10-04 17:28:34 +03:00
if ( _get_table_rate ( hw , & sel , pll - > params - > fixed_rate , input_rate ) )
2013-04-03 17:40:41 +03:00
return - EINVAL ;
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
val = pll_readl_base ( pll ) ;
val & = ~ BIT ( 29 ) ; /* Disable lock override */
pll_writel_base ( val , pll ) ;
val = pll_readl ( pll - > params - > aux_reg , pll ) ;
val | = PLLE_AUX_ENABLE_SWCTL ;
val & = ~ PLLE_AUX_SEQ_ENABLE ;
pll_writel ( val , pll - > params - > aux_reg , pll ) ;
udelay ( 1 ) ;
val = pll_readl_misc ( pll ) ;
val | = PLLE_MISC_LOCK_ENABLE ;
val | = PLLE_MISC_IDDQ_SW_CTRL ;
val & = ~ PLLE_MISC_IDDQ_SW_VALUE ;
val | = PLLE_MISC_PLLE_PTS ;
val | = PLLE_MISC_VREG_BG_CTRL_MASK | PLLE_MISC_VREG_CTRL_MASK ;
pll_writel_misc ( val , pll ) ;
udelay ( 5 ) ;
val = pll_readl ( PLLE_SS_CTRL , pll ) ;
val | = PLLE_SS_DISABLE ;
pll_writel ( val , PLLE_SS_CTRL , pll ) ;
val = pll_readl_base ( pll ) ;
2014-04-04 15:55:14 +02:00
val & = ~ ( divp_mask_shifted ( pll ) | divn_mask_shifted ( pll ) |
divm_mask_shifted ( pll ) ) ;
2014-04-04 15:55:13 +02:00
val & = ~ ( PLLE_BASE_DIVCML_MASK < < PLLE_BASE_DIVCML_SHIFT ) ;
2014-04-04 15:55:14 +02:00
val | = sel . m < < divm_shift ( pll ) ;
val | = sel . n < < divn_shift ( pll ) ;
2013-04-03 17:40:41 +03:00
val | = sel . cpcon < < PLLE_BASE_DIVCML_SHIFT ;
pll_writel_base ( val , pll ) ;
udelay ( 1 ) ;
_clk_pll_enable ( hw ) ;
ret = clk_pll_wait_for_lock ( pll ) ;
if ( ret < 0 )
goto out ;
2013-09-26 18:30:01 +03:00
val = pll_readl ( PLLE_SS_CTRL , pll ) ;
val & = ~ ( PLLE_SS_CNTL_CENTER | PLLE_SS_CNTL_INVERT ) ;
val & = ~ PLLE_SS_COEFFICIENTS_MASK ;
val | = PLLE_SS_COEFFICIENTS_VAL ;
pll_writel ( val , PLLE_SS_CTRL , pll ) ;
val & = ~ ( PLLE_SS_CNTL_SSC_BYP | PLLE_SS_CNTL_BYPASS_SS ) ;
pll_writel ( val , PLLE_SS_CTRL , pll ) ;
udelay ( 1 ) ;
val & = ~ PLLE_SS_CNTL_INTERP_RESET ;
pll_writel ( val , PLLE_SS_CTRL , pll ) ;
udelay ( 1 ) ;
2014-05-14 17:32:57 -07:00
/* Enable hw control of xusb brick pll */
val = pll_readl_misc ( pll ) ;
val & = ~ PLLE_MISC_IDDQ_SW_CTRL ;
pll_writel_misc ( val , pll ) ;
val = pll_readl ( pll - > params - > aux_reg , pll ) ;
val | = ( PLLE_AUX_USE_LOCKDET | PLLE_AUX_SEQ_START_STATE ) ;
val & = ~ ( PLLE_AUX_ENABLE_SWCTL | PLLE_AUX_SS_SWCTL ) ;
pll_writel ( val , pll - > params - > aux_reg , pll ) ;
udelay ( 1 ) ;
val | = PLLE_AUX_SEQ_ENABLE ;
pll_writel ( val , pll - > params - > aux_reg , pll ) ;
val = pll_readl ( XUSBIO_PLL_CFG0 , pll ) ;
val | = ( XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET |
XUSBIO_PLL_CFG0_SEQ_START_STATE ) ;
val & = ~ ( XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL |
XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL ) ;
pll_writel ( val , XUSBIO_PLL_CFG0 , pll ) ;
udelay ( 1 ) ;
val | = XUSBIO_PLL_CFG0_SEQ_ENABLE ;
pll_writel ( val , XUSBIO_PLL_CFG0 , pll ) ;
2013-04-03 17:40:41 +03:00
2014-06-18 17:23:23 +03:00
/* Enable hw control of SATA pll */
val = pll_readl ( SATA_PLL_CFG0 , pll ) ;
val & = ~ SATA_PLL_CFG0_PADPLL_RESET_SWCTL ;
2014-07-08 09:30:15 +02:00
val | = SATA_PLL_CFG0_PADPLL_USE_LOCKDET ;
val | = SATA_PLL_CFG0_SEQ_START_STATE ;
pll_writel ( val , SATA_PLL_CFG0 , pll ) ;
udelay ( 1 ) ;
val = pll_readl ( SATA_PLL_CFG0 , pll ) ;
val | = SATA_PLL_CFG0_SEQ_ENABLE ;
2014-06-18 17:23:23 +03:00
pll_writel ( val , SATA_PLL_CFG0 , pll ) ;
2013-04-03 17:40:41 +03:00
out :
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
return ret ;
}
static void clk_plle_tegra114_disable ( struct clk_hw * hw )
{
struct tegra_clk_pll * pll = to_clk_pll ( hw ) ;
unsigned long flags = 0 ;
u32 val ;
if ( pll - > lock )
spin_lock_irqsave ( pll - > lock , flags ) ;
_clk_pll_disable ( hw ) ;
val = pll_readl_misc ( pll ) ;
val | = PLLE_MISC_IDDQ_SW_CTRL | PLLE_MISC_IDDQ_SW_VALUE ;
pll_writel_misc ( val , pll ) ;
udelay ( 1 ) ;
if ( pll - > lock )
spin_unlock_irqrestore ( pll - > lock , flags ) ;
}
# endif
2013-04-03 17:40:36 +03:00
static struct tegra_clk_pll * _tegra_init_pll ( void __iomem * clk_base ,
2013-10-04 17:28:34 +03:00
void __iomem * pmc , struct tegra_clk_pll_params * pll_params ,
spinlock_t * lock )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
{
struct tegra_clk_pll * pll ;
pll = kzalloc ( sizeof ( * pll ) , GFP_KERNEL ) ;
if ( ! pll )
return ERR_PTR ( - ENOMEM ) ;
pll - > clk_base = clk_base ;
pll - > pmc = pmc ;
pll - > params = pll_params ;
pll - > lock = lock ;
2013-06-05 16:51:25 +03:00
if ( ! pll_params - > div_nmp )
pll_params - > div_nmp = & default_nmp ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
2013-04-03 17:40:36 +03:00
return pll ;
}
static struct clk * _tegra_clk_register_pll ( struct tegra_clk_pll * pll ,
const char * name , const char * parent_name , unsigned long flags ,
const struct clk_ops * ops )
{
struct clk_init_data init ;
init . name = name ;
init . ops = ops ;
init . flags = flags ;
init . parent_names = ( parent_name ? & parent_name : NULL ) ;
init . num_parents = ( parent_name ? 1 : 0 ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
/* Data in .init is copied by clk_register(), so stack variable OK */
pll - > hw . init = & init ;
2013-04-03 17:40:36 +03:00
return clk_register ( NULL , & pll - > hw ) ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
}
struct clk * tegra_clk_register_pll ( const char * name , const char * parent_name ,
void __iomem * clk_base , void __iomem * pmc ,
2013-10-04 17:28:34 +03:00
unsigned long flags , struct tegra_clk_pll_params * pll_params ,
spinlock_t * lock )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
{
2013-04-03 17:40:36 +03:00
struct tegra_clk_pll * pll ;
struct clk * clk ;
2013-10-04 17:28:34 +03:00
pll_params - > flags | = TEGRA_PLL_BYPASS ;
2015-06-18 17:28:23 -04:00
2013-10-04 17:28:34 +03:00
pll = _tegra_init_pll ( clk_base , pmc , pll_params , lock ) ;
2013-04-03 17:40:36 +03:00
if ( IS_ERR ( pll ) )
return ERR_CAST ( pll ) ;
clk = _tegra_clk_register_pll ( pll , name , parent_name , flags ,
& tegra_clk_pll_ops ) ;
if ( IS_ERR ( clk ) )
kfree ( pll ) ;
return clk ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
}
2014-04-04 15:55:13 +02:00
static struct div_nmp pll_e_nmp = {
. divn_shift = PLLE_BASE_DIVN_SHIFT ,
. divn_width = PLLE_BASE_DIVN_WIDTH ,
. divm_shift = PLLE_BASE_DIVM_SHIFT ,
. divm_width = PLLE_BASE_DIVM_WIDTH ,
. divp_shift = PLLE_BASE_DIVP_SHIFT ,
. divp_width = PLLE_BASE_DIVP_WIDTH ,
} ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
struct clk * tegra_clk_register_plle ( const char * name , const char * parent_name ,
void __iomem * clk_base , void __iomem * pmc ,
2013-10-04 17:28:34 +03:00
unsigned long flags , struct tegra_clk_pll_params * pll_params ,
spinlock_t * lock )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
{
2013-04-03 17:40:36 +03:00
struct tegra_clk_pll * pll ;
struct clk * clk ;
2015-06-18 17:28:23 -04:00
pll_params - > flags | = TEGRA_PLL_BYPASS ;
2014-04-04 15:55:13 +02:00
if ( ! pll_params - > div_nmp )
pll_params - > div_nmp = & pll_e_nmp ;
2013-10-04 17:28:34 +03:00
pll = _tegra_init_pll ( clk_base , pmc , pll_params , lock ) ;
2013-04-03 17:40:36 +03:00
if ( IS_ERR ( pll ) )
return ERR_CAST ( pll ) ;
clk = _tegra_clk_register_pll ( pll , name , parent_name , flags ,
& tegra_clk_plle_ops ) ;
if ( IS_ERR ( clk ) )
kfree ( pll ) ;
return clk ;
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
}
2013-04-03 17:40:41 +03:00
2014-12-16 12:38:29 -08:00
# if defined(CONFIG_ARCH_TEGRA_114_SOC) || \
defined ( CONFIG_ARCH_TEGRA_124_SOC ) | | \
defined ( CONFIG_ARCH_TEGRA_132_SOC )
2013-10-08 16:47:41 +05:30
static const struct clk_ops tegra_clk_pllxc_ops = {
2013-04-03 17:40:41 +03:00
. is_enabled = clk_pll_is_enabled ,
2015-06-18 17:28:20 -04:00
. enable = clk_pll_enable ,
. disable = clk_pll_disable ,
2013-04-03 17:40:41 +03:00
. recalc_rate = clk_pll_recalc_rate ,
. round_rate = clk_pll_ramp_round_rate ,
. set_rate = clk_pllxc_set_rate ,
} ;
2013-10-08 16:47:41 +05:30
static const struct clk_ops tegra_clk_pllm_ops = {
2013-04-03 17:40:41 +03:00
. is_enabled = clk_pll_is_enabled ,
2015-06-18 17:28:20 -04:00
. enable = clk_pll_enable ,
. disable = clk_pll_disable ,
2013-04-03 17:40:41 +03:00
. recalc_rate = clk_pll_recalc_rate ,
. round_rate = clk_pll_ramp_round_rate ,
. set_rate = clk_pllm_set_rate ,
} ;
2013-10-08 16:47:41 +05:30
static const struct clk_ops tegra_clk_pllc_ops = {
2013-04-03 17:40:41 +03:00
. is_enabled = clk_pll_is_enabled ,
. enable = clk_pllc_enable ,
. disable = clk_pllc_disable ,
. recalc_rate = clk_pll_recalc_rate ,
. round_rate = clk_pll_ramp_round_rate ,
. set_rate = clk_pllc_set_rate ,
} ;
2013-10-08 16:47:41 +05:30
static const struct clk_ops tegra_clk_pllre_ops = {
2013-04-03 17:40:41 +03:00
. is_enabled = clk_pll_is_enabled ,
2015-06-18 17:28:20 -04:00
. enable = clk_pll_enable ,
. disable = clk_pll_disable ,
2013-04-03 17:40:41 +03:00
. recalc_rate = clk_pllre_recalc_rate ,
. round_rate = clk_pllre_round_rate ,
. set_rate = clk_pllre_set_rate ,
} ;
2013-10-08 16:47:41 +05:30
static const struct clk_ops tegra_clk_plle_tegra114_ops = {
2013-04-03 17:40:41 +03:00
. is_enabled = clk_pll_is_enabled ,
. enable = clk_plle_tegra114_enable ,
. disable = clk_plle_tegra114_disable ,
. recalc_rate = clk_pll_recalc_rate ,
} ;
struct clk * tegra_clk_register_pllxc ( const char * name , const char * parent_name ,
void __iomem * clk_base , void __iomem * pmc ,
2013-10-04 17:28:34 +03:00
unsigned long flags ,
2013-04-03 17:40:41 +03:00
struct tegra_clk_pll_params * pll_params ,
spinlock_t * lock )
{
struct tegra_clk_pll * pll ;
2013-09-06 14:37:37 +03:00
struct clk * clk , * parent ;
unsigned long parent_rate ;
int err ;
u32 val , val_iddq ;
parent = __clk_lookup ( parent_name ) ;
2013-10-29 03:07:57 +01:00
if ( ! parent ) {
2013-09-06 14:37:37 +03:00
WARN ( 1 , " parent clk %s of %s must be registered first \n " ,
2014-09-30 09:22:00 +02:00
parent_name , name ) ;
2013-09-06 14:37:37 +03:00
return ERR_PTR ( - EINVAL ) ;
}
2013-04-03 17:40:41 +03:00
if ( ! pll_params - > pdiv_tohw )
return ERR_PTR ( - EINVAL ) ;
2015-07-30 17:20:57 -07:00
parent_rate = clk_get_rate ( parent ) ;
2013-09-06 14:37:37 +03:00
pll_params - > vco_min = _clip_vco_min ( pll_params - > vco_min , parent_rate ) ;
err = _setup_dynamic_ramp ( pll_params , clk_base , parent_rate ) ;
if ( err )
return ERR_PTR ( err ) ;
val = readl_relaxed ( clk_base + pll_params - > base_reg ) ;
val_iddq = readl_relaxed ( clk_base + pll_params - > iddq_reg ) ;
if ( val & PLL_BASE_ENABLE )
WARN_ON ( val_iddq & BIT ( pll_params - > iddq_bit_idx ) ) ;
else {
val_iddq | = BIT ( pll_params - > iddq_bit_idx ) ;
writel_relaxed ( val_iddq , clk_base + pll_params - > iddq_reg ) ;
}
2013-10-04 17:28:34 +03:00
pll = _tegra_init_pll ( clk_base , pmc , pll_params , lock ) ;
2013-04-03 17:40:41 +03:00
if ( IS_ERR ( pll ) )
return ERR_CAST ( pll ) ;
clk = _tegra_clk_register_pll ( pll , name , parent_name , flags ,
& tegra_clk_pllxc_ops ) ;
if ( IS_ERR ( clk ) )
kfree ( pll ) ;
return clk ;
}
struct clk * tegra_clk_register_pllre ( const char * name , const char * parent_name ,
void __iomem * clk_base , void __iomem * pmc ,
2013-10-04 17:28:34 +03:00
unsigned long flags ,
2013-04-03 17:40:41 +03:00
struct tegra_clk_pll_params * pll_params ,
spinlock_t * lock , unsigned long parent_rate )
{
u32 val ;
struct tegra_clk_pll * pll ;
struct clk * clk ;
2013-09-06 14:37:37 +03:00
pll_params - > vco_min = _clip_vco_min ( pll_params - > vco_min , parent_rate ) ;
2013-10-04 17:28:34 +03:00
pll = _tegra_init_pll ( clk_base , pmc , pll_params , lock ) ;
2013-04-03 17:40:41 +03:00
if ( IS_ERR ( pll ) )
return ERR_CAST ( pll ) ;
/* program minimum rate by default */
val = pll_readl_base ( pll ) ;
if ( val & PLL_BASE_ENABLE )
WARN_ON ( val & pll_params - > iddq_bit_idx ) ;
else {
int m ;
m = _pll_fixed_mdiv ( pll_params , parent_rate ) ;
2014-04-04 15:55:14 +02:00
val = m < < divm_shift ( pll ) ;
val | = ( pll_params - > vco_min / parent_rate ) < < divn_shift ( pll ) ;
2013-04-03 17:40:41 +03:00
pll_writel_base ( val , pll ) ;
}
/* disable lock override */
val = pll_readl_misc ( pll ) ;
val & = ~ BIT ( 29 ) ;
pll_writel_misc ( val , pll ) ;
clk = _tegra_clk_register_pll ( pll , name , parent_name , flags ,
& tegra_clk_pllre_ops ) ;
if ( IS_ERR ( clk ) )
kfree ( pll ) ;
return clk ;
}
struct clk * tegra_clk_register_pllm ( const char * name , const char * parent_name ,
void __iomem * clk_base , void __iomem * pmc ,
2013-10-04 17:28:34 +03:00
unsigned long flags ,
2013-04-03 17:40:41 +03:00
struct tegra_clk_pll_params * pll_params ,
spinlock_t * lock )
{
struct tegra_clk_pll * pll ;
2013-09-06 14:37:37 +03:00
struct clk * clk , * parent ;
unsigned long parent_rate ;
2013-04-03 17:40:41 +03:00
if ( ! pll_params - > pdiv_tohw )
return ERR_PTR ( - EINVAL ) ;
2013-09-06 14:37:37 +03:00
parent = __clk_lookup ( parent_name ) ;
2013-10-29 03:07:57 +01:00
if ( ! parent ) {
2013-09-06 14:37:37 +03:00
WARN ( 1 , " parent clk %s of %s must be registered first \n " ,
2014-09-30 09:22:00 +02:00
parent_name , name ) ;
2013-09-06 14:37:37 +03:00
return ERR_PTR ( - EINVAL ) ;
}
2015-07-30 17:20:57 -07:00
parent_rate = clk_get_rate ( parent ) ;
2013-09-06 14:37:37 +03:00
pll_params - > vco_min = _clip_vco_min ( pll_params - > vco_min , parent_rate ) ;
2013-10-04 17:28:34 +03:00
pll_params - > flags | = TEGRA_PLL_BYPASS ;
pll_params - > flags | = TEGRA_PLLM ;
pll = _tegra_init_pll ( clk_base , pmc , pll_params , lock ) ;
2013-04-03 17:40:41 +03:00
if ( IS_ERR ( pll ) )
return ERR_CAST ( pll ) ;
clk = _tegra_clk_register_pll ( pll , name , parent_name , flags ,
& tegra_clk_pllm_ops ) ;
if ( IS_ERR ( clk ) )
kfree ( pll ) ;
return clk ;
}
struct clk * tegra_clk_register_pllc ( const char * name , const char * parent_name ,
void __iomem * clk_base , void __iomem * pmc ,
2013-10-04 17:28:34 +03:00
unsigned long flags ,
2013-04-03 17:40:41 +03:00
struct tegra_clk_pll_params * pll_params ,
spinlock_t * lock )
{
struct clk * parent , * clk ;
2015-11-19 16:34:06 +01:00
const struct pdiv_map * p_tohw = pll_params - > pdiv_tohw ;
2013-04-03 17:40:41 +03:00
struct tegra_clk_pll * pll ;
struct tegra_clk_pll_freq_table cfg ;
unsigned long parent_rate ;
if ( ! p_tohw )
return ERR_PTR ( - EINVAL ) ;
parent = __clk_lookup ( parent_name ) ;
2013-10-29 03:07:57 +01:00
if ( ! parent ) {
2013-04-03 17:40:41 +03:00
WARN ( 1 , " parent clk %s of %s must be registered first \n " ,
2014-09-30 09:22:00 +02:00
parent_name , name ) ;
2013-04-03 17:40:41 +03:00
return ERR_PTR ( - EINVAL ) ;
}
2015-07-30 17:20:57 -07:00
parent_rate = clk_get_rate ( parent ) ;
2013-09-06 14:37:37 +03:00
pll_params - > vco_min = _clip_vco_min ( pll_params - > vco_min , parent_rate ) ;
2013-10-04 17:28:34 +03:00
pll_params - > flags | = TEGRA_PLL_BYPASS ;
pll = _tegra_init_pll ( clk_base , pmc , pll_params , lock ) ;
2013-04-03 17:40:41 +03:00
if ( IS_ERR ( pll ) )
return ERR_CAST ( pll ) ;
/*
* Most of PLLC register fields are shadowed , and can not be read
* directly from PLL h / w . Hence , actual PLLC boot state is unknown .
* Initialize PLL to default state : disabled , reset ; shadow registers
* loaded with default parameters ; dividers are preset for half of
* minimum VCO rate ( the latter assured that shadowed divider settings
* are within supported range ) .
*/
cfg . m = _pll_fixed_mdiv ( pll_params , parent_rate ) ;
cfg . n = cfg . m * pll_params - > vco_min / parent_rate ;
while ( p_tohw - > pdiv ) {
if ( p_tohw - > pdiv = = 2 ) {
cfg . p = p_tohw - > hw_val ;
break ;
}
p_tohw + + ;
}
if ( ! p_tohw - > pdiv ) {
WARN_ON ( 1 ) ;
return ERR_PTR ( - EINVAL ) ;
}
pll_writel_base ( 0 , pll ) ;
_update_pll_mnp ( pll , & cfg ) ;
pll_writel_misc ( PLLCX_MISC_DEFAULT , pll ) ;
pll_writel ( PLLCX_MISC1_DEFAULT , pll_params - > ext_misc_reg [ 0 ] , pll ) ;
pll_writel ( PLLCX_MISC2_DEFAULT , pll_params - > ext_misc_reg [ 1 ] , pll ) ;
pll_writel ( PLLCX_MISC3_DEFAULT , pll_params - > ext_misc_reg [ 2 ] , pll ) ;
_pllcx_update_dynamic_coef ( pll , parent_rate , cfg . n ) ;
clk = _tegra_clk_register_pll ( pll , name , parent_name , flags ,
& tegra_clk_pllc_ops ) ;
if ( IS_ERR ( clk ) )
kfree ( pll ) ;
return clk ;
}
struct clk * tegra_clk_register_plle_tegra114 ( const char * name ,
const char * parent_name ,
void __iomem * clk_base , unsigned long flags ,
struct tegra_clk_pll_params * pll_params ,
spinlock_t * lock )
{
struct tegra_clk_pll * pll ;
struct clk * clk ;
u32 val , val_aux ;
2013-10-04 17:28:34 +03:00
pll = _tegra_init_pll ( clk_base , NULL , pll_params , lock ) ;
2013-04-03 17:40:41 +03:00
if ( IS_ERR ( pll ) )
return ERR_CAST ( pll ) ;
/* ensure parent is set to pll_re_vco */
val = pll_readl_base ( pll ) ;
val_aux = pll_readl ( pll_params - > aux_reg , pll ) ;
if ( val & PLL_BASE_ENABLE ) {
2013-11-25 14:44:13 +02:00
if ( ( val_aux & PLLE_AUX_PLLRE_SEL ) | |
( val_aux & PLLE_AUX_PLLP_SEL ) )
2013-04-03 17:40:41 +03:00
WARN ( 1 , " pll_e enabled with unsupported parent %s \n " ,
2013-11-25 14:44:13 +02:00
( val_aux & PLLE_AUX_PLLP_SEL ) ? " pllp_out0 " :
" pll_re_vco " ) ;
2013-04-03 17:40:41 +03:00
} else {
2013-11-25 14:44:13 +02:00
val_aux & = ~ ( PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL ) ;
2014-05-16 16:50:20 +03:00
pll_writel ( val_aux , pll_params - > aux_reg , pll ) ;
2013-04-03 17:40:41 +03:00
}
clk = _tegra_clk_register_pll ( pll , name , parent_name , flags ,
& tegra_clk_plle_tegra114_ops ) ;
if ( IS_ERR ( clk ) )
kfree ( pll ) ;
return clk ;
}
# endif
2013-09-09 13:22:55 +03:00
2014-12-16 12:38:29 -08:00
# if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
2013-10-08 16:47:41 +05:30
static const struct clk_ops tegra_clk_pllss_ops = {
2013-09-09 13:22:55 +03:00
. is_enabled = clk_pll_is_enabled ,
2015-06-18 17:28:20 -04:00
. enable = clk_pll_enable ,
. disable = clk_pll_disable ,
2013-09-09 13:22:55 +03:00
. recalc_rate = clk_pll_recalc_rate ,
. round_rate = clk_pll_ramp_round_rate ,
. set_rate = clk_pllxc_set_rate ,
} ;
struct clk * tegra_clk_register_pllss ( const char * name , const char * parent_name ,
void __iomem * clk_base , unsigned long flags ,
struct tegra_clk_pll_params * pll_params ,
spinlock_t * lock )
{
struct tegra_clk_pll * pll ;
struct clk * clk , * parent ;
struct tegra_clk_pll_freq_table cfg ;
unsigned long parent_rate ;
u32 val ;
int i ;
if ( ! pll_params - > div_nmp )
return ERR_PTR ( - EINVAL ) ;
parent = __clk_lookup ( parent_name ) ;
2013-10-29 03:07:57 +01:00
if ( ! parent ) {
2013-09-09 13:22:55 +03:00
WARN ( 1 , " parent clk %s of %s must be registered first \n " ,
2014-09-30 09:22:00 +02:00
parent_name , name ) ;
2013-09-09 13:22:55 +03:00
return ERR_PTR ( - EINVAL ) ;
}
pll = _tegra_init_pll ( clk_base , NULL , pll_params , lock ) ;
if ( IS_ERR ( pll ) )
return ERR_CAST ( pll ) ;
val = pll_readl_base ( pll ) ;
val & = ~ PLLSS_REF_SRC_SEL_MASK ;
pll_writel_base ( val , pll ) ;
2015-07-30 17:20:57 -07:00
parent_rate = clk_get_rate ( parent ) ;
2013-09-09 13:22:55 +03:00
pll_params - > vco_min = _clip_vco_min ( pll_params - > vco_min , parent_rate ) ;
/* initialize PLL to minimum rate */
cfg . m = _pll_fixed_mdiv ( pll_params , parent_rate ) ;
cfg . n = cfg . m * pll_params - > vco_min / parent_rate ;
for ( i = 0 ; pll_params - > pdiv_tohw [ i ] . pdiv ; i + + )
;
if ( ! i ) {
kfree ( pll ) ;
return ERR_PTR ( - EINVAL ) ;
}
cfg . p = pll_params - > pdiv_tohw [ i - 1 ] . hw_val ;
_update_pll_mnp ( pll , & cfg ) ;
pll_writel_misc ( PLLSS_MISC_DEFAULT , pll ) ;
pll_writel ( PLLSS_CFG_DEFAULT , pll_params - > ext_misc_reg [ 0 ] , pll ) ;
pll_writel ( PLLSS_CTRL1_DEFAULT , pll_params - > ext_misc_reg [ 1 ] , pll ) ;
pll_writel ( PLLSS_CTRL1_DEFAULT , pll_params - > ext_misc_reg [ 2 ] , pll ) ;
val = pll_readl_base ( pll ) ;
if ( val & PLL_BASE_ENABLE ) {
if ( val & BIT ( pll_params - > iddq_bit_idx ) ) {
WARN ( 1 , " %s is on but IDDQ set \n " , name ) ;
kfree ( pll ) ;
return ERR_PTR ( - EINVAL ) ;
}
} else
val | = BIT ( pll_params - > iddq_bit_idx ) ;
val & = ~ PLLSS_LOCK_OVERRIDE ;
pll_writel_base ( val , pll ) ;
clk = _tegra_clk_register_pll ( pll , name , parent_name , flags ,
& tegra_clk_pllss_ops ) ;
if ( IS_ERR ( clk ) )
kfree ( pll ) ;
return clk ;
}
# endif