summaryrefslogtreecommitdiff
path: root/drivers/clk/tegra/clk.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/tegra/clk.h')
-rw-r--r--drivers/clk/tegra/clk.h101
1 files changed, 98 insertions, 3 deletions
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 5d2678914160..4dbcfaec576a 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -110,14 +110,16 @@ struct clk *tegra_clk_register_mc(const char *name, const char *parent_name,
* @m: input divider
* @p: post divider
* @cpcon: charge pump current
+ * @sdm_data: fraction divider setting (0 = disabled)
*/
struct tegra_clk_pll_freq_table {
unsigned long input_rate;
unsigned long output_rate;
- u16 n;
+ u32 n;
u16 m;
u8 p;
u8 cpcon;
+ u16 sdm_data;
};
/**
@@ -156,6 +158,10 @@ struct div_nmp {
u8 override_divp_shift;
};
+#define MAX_PLL_MISC_REG_COUNT 6
+
+struct tegra_clk_pll;
+
/**
* struct tegra_clk_pll_params - PLL parameters
*
@@ -172,6 +178,14 @@ struct div_nmp {
* @lock_enable_bit_idx: Bit index to enable PLL lock
* @iddq_reg: PLL IDDQ register offset
* @iddq_bit_idx: Bit index to enable PLL IDDQ
+ * @reset_reg: Register offset of where RESET bit is
+ * @reset_bit_idx: Shift of reset bit in reset_reg
+ * @sdm_din_reg: Register offset where SDM settings are
+ * @sdm_din_mask: Mask of SDM divider bits
+ * @sdm_ctrl_reg: Register offset where SDM enable is
+ * @sdm_ctrl_en_mask: Mask of SDM enable bit
+ * @ssc_ctrl_reg: Register offset where SSC settings are
+ * @ssc_ctrl_en_mask: Mask of SSC enable bit
* @aux_reg: AUX register offset
* @dyn_ramp_reg: Dynamic ramp control register offset
* @ext_misc_reg: Miscellaneous control register offsets
@@ -182,10 +196,27 @@ struct div_nmp {
* @stepb_shift: Dynamic ramp step B field shift
* @lock_delay: Delay in us if PLL lock is not used
* @max_p: maximum value for the p divider
+ * @defaults_set: Boolean signaling all reg defaults for PLL set.
* @pdiv_tohw: mapping of p divider to register values
* @div_nmp: offsets and widths on n, m and p fields
* @freq_table: array of frequencies supported by PLL
* @fixed_rate: PLL rate if it is fixed
+ * @mdiv_default: Default value for fixed mdiv for this PLL
+ * @round_p_to_pdiv: Callback used to round p to the closed pdiv
+ * @set_gain: Callback to adjust N div for SDM enabled
+ * PLL's based on fractional divider value.
+ * @calc_rate: Callback used to change how out of table
+ * rates (dividers and multipler) are calculated.
+ * @adjust_vco: Callback to adjust the programming range of the
+ * divider range (if SDM is present)
+ * @set_defaults: Callback which will try to initialize PLL
+ * registers to sane default values. This is first
+ * tried during PLL registration, but if the PLL
+ * is already enabled, it will be done the first
+ * time the rate is changed while the PLL is
+ * disabled.
+ * @dyn_ramp: Callback which can be used to define a custom
+ * dynamic ramp function for a given PLL.
*
* Flags:
* TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
@@ -207,6 +238,11 @@ struct div_nmp {
* base register.
* TEGRA_PLL_BYPASS - PLL has bypass bit
* TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
+ * TEGRA_MDIV_NEW - Switch to new method for calculating fixed mdiv
+ * it may be more accurate (especially if SDM present)
+ * TEGRA_PLLMB - PLLMB has should be treated similar to PLLM. This
+ * flag indicated that it is PLLMB.
+ * TEGRA_PLL_VCO_OUT - Used to indicate that the PLL has a VCO output
*/
struct tegra_clk_pll_params {
unsigned long input_min;
@@ -223,9 +259,17 @@ struct tegra_clk_pll_params {
u32 lock_enable_bit_idx;
u32 iddq_reg;
u32 iddq_bit_idx;
+ u32 reset_reg;
+ u32 reset_bit_idx;
+ u32 sdm_din_reg;
+ u32 sdm_din_mask;
+ u32 sdm_ctrl_reg;
+ u32 sdm_ctrl_en_mask;
+ u32 ssc_ctrl_reg;
+ u32 ssc_ctrl_en_mask;
u32 aux_reg;
u32 dyn_ramp_reg;
- u32 ext_misc_reg[3];
+ u32 ext_misc_reg[MAX_PLL_MISC_REG_COUNT];
u32 pmc_divnm_reg;
u32 pmc_divp_reg;
u32 flags;
@@ -233,10 +277,22 @@ struct tegra_clk_pll_params {
int stepb_shift;
int lock_delay;
int max_p;
- struct pdiv_map *pdiv_tohw;
+ bool defaults_set;
+ const struct pdiv_map *pdiv_tohw;
struct div_nmp *div_nmp;
struct tegra_clk_pll_freq_table *freq_table;
unsigned long fixed_rate;
+ u16 mdiv_default;
+ u32 (*round_p_to_pdiv)(u32 p, u32 *pdiv);
+ void (*set_gain)(struct tegra_clk_pll_freq_table *cfg);
+ int (*calc_rate)(struct clk_hw *hw,
+ struct tegra_clk_pll_freq_table *cfg,
+ unsigned long rate, unsigned long parent_rate);
+ unsigned long (*adjust_vco)(struct tegra_clk_pll_params *pll_params,
+ unsigned long parent_rate);
+ void (*set_defaults)(struct tegra_clk_pll *pll);
+ int (*dyn_ramp)(struct tegra_clk_pll *pll,
+ struct tegra_clk_pll_freq_table *cfg);
};
#define TEGRA_PLL_USE_LOCK BIT(0)
@@ -250,6 +306,9 @@ struct tegra_clk_pll_params {
#define TEGRA_PLL_LOCK_MISC BIT(8)
#define TEGRA_PLL_BYPASS BIT(9)
#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
+#define TEGRA_MDIV_NEW BIT(11)
+#define TEGRA_PLLMB BIT(12)
+#define TEGRA_PLL_VCO_OUT BIT(13)
/**
* struct tegra_clk_pll - Tegra PLL clock
@@ -303,6 +362,12 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
+struct clk *tegra_clk_register_pllxc_tegra210(const char *name,
+ const char *parent_name, void __iomem *clk_base,
+ void __iomem *pmc, unsigned long flags,
+ struct tegra_clk_pll_params *pll_params,
+ spinlock_t *lock);
+
struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
void __iomem *clk_base, void __iomem *pmc,
unsigned long flags,
@@ -327,11 +392,35 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
+struct clk *tegra_clk_register_plle_tegra210(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 clk *tegra_clk_register_pllc_tegra210(const char *name,
+ const char *parent_name, void __iomem *clk_base,
+ void __iomem *pmc, unsigned long flags,
+ struct tegra_clk_pll_params *pll_params,
+ spinlock_t *lock);
+
+struct clk *tegra_clk_register_pllss_tegra210(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 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 clk *tegra_clk_register_pllmb(const char *name, const char *parent_name,
+ void __iomem *clk_base, void __iomem *pmc,
+ unsigned long flags,
+ struct tegra_clk_pll_params *pll_params,
+ spinlock_t *lock);
+
/**
* struct tegra_clk_pll_out - PLL divider down clock
*
@@ -653,6 +742,9 @@ int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
void tegra_super_clk_gen4_init(void __iomem *clk_base,
void __iomem *pmc_base, struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *pll_params);
+void tegra_super_clk_gen5_init(void __iomem *clk_base,
+ void __iomem *pmc_base, struct tegra_clk *tegra_clks,
+ struct tegra_clk_pll_params *pll_params);
#ifdef CONFIG_TEGRA_CLK_EMC
struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
@@ -674,5 +766,8 @@ void tegra114_clock_deassert_dfll_dvco_reset(void);
typedef void (*tegra_clk_apply_init_table_func)(void);
extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
+int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll);
+u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate);
+int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
#endif /* TEGRA_CLK_H */