aboutsummaryrefslogtreecommitdiff
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.h237
1 files changed, 184 insertions, 53 deletions
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 0744731c622..16ec8d6bb87 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -1,4 +1,4 @@
-/*
+ /*
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -37,6 +37,8 @@ struct tegra_clk_sync_source {
container_of(_hw, struct tegra_clk_sync_source, hw)
extern const struct clk_ops tegra_clk_sync_source_ops;
+extern int *periph_clk_enb_refcnt;
+
struct clk *tegra_clk_register_sync_source(const char *name,
unsigned long fixed_rate, unsigned long max_rate);
@@ -117,6 +119,42 @@ struct tegra_clk_pll_freq_table {
};
/**
+ * struct pdiv_map - map post divider to hw value
+ *
+ * @pdiv: post divider
+ * @hw_val: value to be written to the PLL hw
+ */
+struct pdiv_map {
+ u8 pdiv;
+ u8 hw_val;
+};
+
+/**
+ * struct div_nmp - offset and width of m,n and p fields
+ *
+ * @divn_shift: shift to the feedback divider bit field
+ * @divn_width: width of the feedback divider bit field
+ * @divm_shift: shift to the input divider bit field
+ * @divm_width: width of the input divider bit field
+ * @divp_shift: shift to the post divider bit field
+ * @divp_width: width of the post divider bit field
+ * @override_divn_shift: shift to the feedback divider bitfield in override reg
+ * @override_divm_shift: shift to the input divider bitfield in override reg
+ * @override_divp_shift: shift to the post divider bitfield in override reg
+ */
+struct div_nmp {
+ u8 divn_shift;
+ u8 divn_width;
+ u8 divm_shift;
+ u8 divm_width;
+ u8 divp_shift;
+ u8 divp_width;
+ u8 override_divn_shift;
+ u8 override_divm_shift;
+ u8 override_divp_shift;
+};
+
+/**
* struct clk_pll_params - PLL parameters
*
* @input_min: Minimum input frequency
@@ -143,9 +181,24 @@ struct tegra_clk_pll_params {
u32 base_reg;
u32 misc_reg;
u32 lock_reg;
- u32 lock_bit_idx;
+ u32 lock_mask;
u32 lock_enable_bit_idx;
+ u32 iddq_reg;
+ u32 iddq_bit_idx;
+ u32 aux_reg;
+ u32 dyn_ramp_reg;
+ u32 ext_misc_reg[3];
+ u32 pmc_divnm_reg;
+ u32 pmc_divp_reg;
+ u32 flags;
+ int stepa_shift;
+ int stepb_shift;
int lock_delay;
+ int max_p;
+ struct pdiv_map *pdiv_tohw;
+ struct div_nmp *div_nmp;
+ struct tegra_clk_pll_freq_table *freq_table;
+ unsigned long fixed_rate;
};
/**
@@ -159,12 +212,6 @@ struct tegra_clk_pll_params {
* @flags: PLL flags
* @fixed_rate: PLL rate if it is fixed
* @lock: register lock
- * @divn_shift: shift to the feedback divider bit field
- * @divn_width: width of the feedback divider bit field
- * @divm_shift: shift to the input divider bit field
- * @divm_width: width of the input divider bit field
- * @divp_shift: shift to the post divider bit field
- * @divp_width: width of the post divider bit field
*
* Flags:
* TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
@@ -182,21 +229,16 @@ struct tegra_clk_pll_params {
* TEGRA_PLL_FIXED - We are not supposed to change output frequency
* of some plls.
* TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
+ * TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the
+ * base register.
+ * TEGRA_PLL_BYPASS - PLL has bypass bit
+ * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
*/
struct tegra_clk_pll {
struct clk_hw hw;
void __iomem *clk_base;
void __iomem *pmc;
- u8 flags;
- unsigned long fixed_rate;
spinlock_t *lock;
- u8 divn_shift;
- u8 divn_width;
- u8 divm_shift;
- u8 divm_width;
- u8 divp_shift;
- u8 divp_width;
- struct tegra_clk_pll_freq_table *freq_table;
struct tegra_clk_pll_params *params;
};
@@ -210,19 +252,56 @@ struct tegra_clk_pll {
#define TEGRA_PLLM BIT(5)
#define TEGRA_PLL_FIXED BIT(6)
#define TEGRA_PLLE_CONFIGURE BIT(7)
+#define TEGRA_PLL_LOCK_MISC BIT(8)
+#define TEGRA_PLL_BYPASS BIT(9)
+#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
extern const struct clk_ops tegra_clk_pll_ops;
extern const struct clk_ops tegra_clk_plle_ops;
struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags, unsigned long fixed_rate,
- struct tegra_clk_pll_params *pll_params, u8 pll_flags,
- struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock);
+ unsigned long flags, struct tegra_clk_pll_params *pll_params,
+ spinlock_t *lock);
+
struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags, unsigned long fixed_rate,
- struct tegra_clk_pll_params *pll_params, u8 pll_flags,
- struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock);
+ unsigned long flags, struct tegra_clk_pll_params *pll_params,
+ spinlock_t *lock);
+
+struct clk *tegra_clk_register_pllxc(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,
+ struct tegra_clk_pll_params *pll_params,
+ spinlock_t *lock);
+
+struct clk *tegra_clk_register_pllc(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_pllre(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, unsigned long parent_rate);
+
+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 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_out - PLL divider down clock
@@ -290,6 +369,7 @@ struct tegra_clk_periph_regs {
* TEGRA_PERIPH_ON_APB - If peripheral is in the APB bus then read the
* bus to flush the write operation in apb bus. This flag indicates
* that this peripheral is in apb bus.
+ * TEGRA_PERIPH_WAR_1005168 - Apply workaround for Tegra114 MSENC bug
*/
struct tegra_clk_periph_gate {
u32 magic;
@@ -309,13 +389,14 @@ struct tegra_clk_periph_gate {
#define TEGRA_PERIPH_NO_RESET BIT(0)
#define TEGRA_PERIPH_MANUAL_RESET BIT(1)
#define TEGRA_PERIPH_ON_APB BIT(2)
+#define TEGRA_PERIPH_WAR_1005168 BIT(3)
+#define TEGRA_PERIPH_NO_DIV BIT(4)
+#define TEGRA_PERIPH_NO_GATE BIT(5)
-void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert);
extern const struct clk_ops tegra_clk_periph_gate_ops;
struct clk *tegra_clk_register_periph_gate(const char *name,
const char *parent_name, u8 gate_flags, void __iomem *clk_base,
- unsigned long flags, int clk_num,
- struct tegra_clk_periph_regs *pregs, int *enable_refcnt);
+ unsigned long flags, int clk_num, int *enable_refcnt);
/**
* struct clk-periph - peripheral clock
@@ -349,33 +430,34 @@ extern const struct clk_ops tegra_clk_periph_ops;
struct clk *tegra_clk_register_periph(const char *name,
const char **parent_names, int num_parents,
struct tegra_clk_periph *periph, void __iomem *clk_base,
- u32 offset);
+ u32 offset, unsigned long flags);
struct clk *tegra_clk_register_periph_nodiv(const char *name,
const char **parent_names, int num_parents,
struct tegra_clk_periph *periph, void __iomem *clk_base,
u32 offset);
-#define TEGRA_CLK_PERIPH(_mux_shift, _mux_width, _mux_flags, \
+#define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \
_div_shift, _div_width, _div_frac_width, \
- _div_flags, _clk_num, _enb_refcnt, _regs, \
- _gate_flags) \
+ _div_flags, _clk_num,\
+ _gate_flags, _table, _lock) \
{ \
.mux = { \
.flags = _mux_flags, \
.shift = _mux_shift, \
- .width = _mux_width, \
+ .mask = _mux_mask, \
+ .table = _table, \
+ .lock = _lock, \
}, \
.divider = { \
.flags = _div_flags, \
.shift = _div_shift, \
.width = _div_width, \
.frac_width = _div_frac_width, \
+ .lock = _lock, \
}, \
.gate = { \
.flags = _gate_flags, \
.clk_num = _clk_num, \
- .enable_refcnt = _enb_refcnt, \
- .regs = _regs, \
}, \
.mux_ops = &clk_mux_ops, \
.div_ops = &tegra_clk_frac_div_ops, \
@@ -385,34 +467,49 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,
struct tegra_periph_init_data {
const char *name;
int clk_id;
- const char **parent_names;
+ union {
+ const char **parent_names;
+ const char *parent_name;
+ } p;
int num_parents;
struct tegra_clk_periph periph;
u32 offset;
const char *con_id;
const char *dev_id;
+ unsigned long flags;
};
-#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset, \
- _mux_shift, _mux_width, _mux_flags, _div_shift, \
- _div_width, _div_frac_width, _div_flags, _regs, \
- _clk_num, _enb_refcnt, _gate_flags, _clk_id) \
+#define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
+ _mux_shift, _mux_mask, _mux_flags, _div_shift, \
+ _div_width, _div_frac_width, _div_flags, \
+ _clk_num, _gate_flags, _clk_id, _table, \
+ _flags, _lock) \
{ \
.name = _name, \
.clk_id = _clk_id, \
- .parent_names = _parent_names, \
+ .p.parent_names = _parent_names, \
.num_parents = ARRAY_SIZE(_parent_names), \
- .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_width, \
+ .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, \
_mux_flags, _div_shift, \
_div_width, _div_frac_width, \
_div_flags, _clk_num, \
- _enb_refcnt, _regs, \
- _gate_flags), \
+ _gate_flags, _table, _lock), \
.offset = _offset, \
.con_id = _con_id, \
.dev_id = _dev_id, \
+ .flags = _flags \
}
+#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\
+ _mux_shift, _mux_width, _mux_flags, _div_shift, \
+ _div_width, _div_frac_width, _div_flags, \
+ _clk_num, _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
+ _mux_shift, BIT(_mux_width) - 1, _mux_flags, \
+ _div_shift, _div_width, _div_frac_width, _div_flags, \
+ _clk_num, _gate_flags, _clk_id,\
+ NULL, 0, NULL)
+
/**
* struct clk_super_mux - super clock
*
@@ -481,22 +578,56 @@ struct tegra_clk_duplicate {
}, \
}
+struct tegra_clk {
+ int dt_id;
+ bool present;
+};
+
+struct tegra_devclk {
+ int dt_id;
+ char *dev_id;
+ char *con_id;
+};
+
void tegra_init_from_table(struct tegra_clk_init_table *tbl,
struct clk *clks[], int clk_max);
void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
struct clk *clks[], int clk_max);
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-void tegra20_clock_init(struct device_node *np);
-#else
-static inline void tegra20_clock_init(struct device_node *np) {}
-#endif /* CONFIG_ARCH_TEGRA_2x_SOC */
-
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-void tegra30_clock_init(struct device_node *np);
-#else
-static inline void tegra30_clock_init(struct device_node *np) {}
-#endif /* CONFIG_ARCH_TEGRA_3x_SOC */
+struct tegra_clk_periph_regs *get_reg_bank(int clkid);
+struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks);
+
+struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk);
+
+void tegra_add_of_provider(struct device_node *np);
+void tegra_register_devclks(struct tegra_devclk *dev_clks, int num);
+
+void tegra_audio_clk_init(void __iomem *clk_base,
+ void __iomem *pmc_base, struct tegra_clk *tegra_clks,
+ struct tegra_clk_pll_params *pll_params);
+
+void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base,
+ struct tegra_clk *tegra_clks,
+ struct tegra_clk_pll_params *pll_params);
+
+void tegra_pmc_clk_init(void __iomem *pmc_base, struct tegra_clk *tegra_clks);
+void tegra_fixed_clk_init(struct tegra_clk *tegra_clks);
+int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *tegra_clks,
+ unsigned long *input_freqs, int num,
+ unsigned long *osc_freq,
+ unsigned long *pll_ref_freq);
+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 tegra114_clock_tune_cpu_trimmers_high(void);
+void tegra114_clock_tune_cpu_trimmers_low(void);
+void tegra114_clock_tune_cpu_trimmers_init(void);
+void tegra114_clock_assert_dfll_dvco_reset(void);
+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;
#endif /* TEGRA_CLK_H */