forked from luck/tmp_suning_uos_patched
Merge branches 'clk-mvebu-periph-pm', 'clk-meson', 'clk-allwinner', 'clk-mvebu-dup' and 'clk-davinci' into clk-next
- S2RAM support for Marvell mvebu periph clks * clk-mvebu-periph-pm: clk: mvebu: armada-37xx-periph: add suspend/resume support clk: mvebu: armada-37xx-periph: save the IP base address in the driver data * clk-meson: clk: meson: meson8b: use the regmap in the internal reset controller clk: meson: meson8b: register the clock controller early clk: meson-axg: pcie: drop the mpll3 clock parent clk: meson: axg: round audio system master clocks down clk: meson: clk-pll: drop hard-coded rates from pll tables clk: meson: clk-pll: remove od parameters clk: meson: clk-pll: drop CLK_GET_RATE_NOCACHE where unnecessary clk: meson: clk-pll: add enable bit * clk-allwinner: dt-bindings: clock: sun50i-a64-ccu: Add PLL_VIDEO0 macro clk: sunxi-ng: a64: Add max. rate constraint to video PLLs clk: sunxi-ng: a64: Add minimal rate for video PLLs clk: sunxi-ng: sun50i: h6: Add 2x fixed post-divider to MMC module clocks clk: sunxi-ng: a83t: Add max. rate constraint to video PLLs clk: sunxi-ng: nkmp: Add constraint for maximum rate clk: sunxi-ng: r40: Add max. rate constraint to video PLLs clk: sunxi-ng: h3/h5: Add max. rate constraint to pll-video clk: sunxi-ng: Add maximum rate constraint to NM PLLs clk: sunxi-ng: h6: fix PWM gate/reset offset clk: sunxi-ng: h6: fix bus clocks' divider position * clk-mvebu-dup: clk: mvebu: ap806: Remove superfluous of_clk_add_provider * clk-davinci: clk: davinci: kill davinci_clk_reset_assert/deassert()
This commit is contained in:
commit
cd8ca30052
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* arch/arm/mach-davinci/include/mach/clock.h
|
||||
*
|
||||
* Clock control driver for DaVinci - header file
|
||||
*
|
||||
* Authors: Vladimir Barinov <source@mvista.com>
|
||||
*
|
||||
* 2007 (c) MontaVista Software, Inc. This file is licensed under
|
||||
* the terms of the GNU General Public License version 2. This program
|
||||
* is licensed "as is" without any warranty of any kind, whether express
|
||||
* or implied.
|
||||
*/
|
||||
#ifndef __ASM_ARCH_DAVINCI_CLOCK_H
|
||||
#define __ASM_ARCH_DAVINCI_CLOCK_H
|
||||
|
||||
struct clk;
|
||||
|
||||
int davinci_clk_reset_assert(struct clk *c);
|
||||
int davinci_clk_reset_deassert(struct clk *c);
|
||||
|
||||
#endif
|
|
@ -303,24 +303,6 @@ static int davinci_lpsc_clk_reset(struct clk *clk, bool reset)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* REVISIT: These exported functions can be removed after a non-DT lookup is
|
||||
* added to the reset controller framework and the davinci-rproc driver is
|
||||
* updated to use the generic reset controller framework.
|
||||
*/
|
||||
|
||||
int davinci_clk_reset_assert(struct clk *clk)
|
||||
{
|
||||
return davinci_lpsc_clk_reset(clk, true);
|
||||
}
|
||||
EXPORT_SYMBOL(davinci_clk_reset_assert);
|
||||
|
||||
int davinci_clk_reset_deassert(struct clk *clk)
|
||||
{
|
||||
return davinci_lpsc_clk_reset(clk, false);
|
||||
}
|
||||
EXPORT_SYMBOL(davinci_clk_reset_deassert);
|
||||
|
||||
static int davinci_psc_reset_assert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
|
|
|
@ -101,10 +101,16 @@ static const char * const mst_mux_parent_names[] = {
|
|||
"axg_mst_in4", "axg_mst_in5", "axg_mst_in6", "axg_mst_in7",
|
||||
};
|
||||
|
||||
#define AXG_MST_MCLK_MUX(_name, _reg) \
|
||||
AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, CLK_MUX_ROUND_CLOSEST, \
|
||||
#define AXG_MST_MUX(_name, _reg, _flag) \
|
||||
AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \
|
||||
mst_mux_parent_names, CLK_SET_RATE_PARENT)
|
||||
|
||||
#define AXG_MST_MCLK_MUX(_name, _reg) \
|
||||
AXG_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST)
|
||||
|
||||
#define AXG_MST_SYS_MUX(_name, _reg) \
|
||||
AXG_MST_MUX(_name, _reg, 0)
|
||||
|
||||
static AXG_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL);
|
||||
static AXG_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL);
|
||||
static AXG_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL);
|
||||
|
@ -112,13 +118,19 @@ static AXG_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL);
|
|||
static AXG_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL);
|
||||
static AXG_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL);
|
||||
static AXG_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL);
|
||||
static AXG_MST_MCLK_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
|
||||
static AXG_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0);
|
||||
static AXG_MST_MCLK_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1);
|
||||
static AXG_MST_SYS_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
|
||||
static AXG_MST_SYS_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1);
|
||||
|
||||
#define AXG_MST_MCLK_DIV(_name, _reg) \
|
||||
AXG_AUD_DIV(_name##_div, _reg, 0, 16, CLK_DIVIDER_ROUND_CLOSEST, \
|
||||
"axg_"#_name"_sel", CLK_SET_RATE_PARENT) \
|
||||
#define AXG_MST_DIV(_name, _reg, _flag) \
|
||||
AXG_AUD_DIV(_name##_div, _reg, 0, 16, _flag, \
|
||||
"axg_"#_name"_sel", CLK_SET_RATE_PARENT) \
|
||||
|
||||
#define AXG_MST_MCLK_DIV(_name, _reg) \
|
||||
AXG_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST)
|
||||
|
||||
#define AXG_MST_SYS_DIV(_name, _reg) \
|
||||
AXG_MST_DIV(_name, _reg, 0)
|
||||
|
||||
static AXG_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL);
|
||||
static AXG_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL);
|
||||
|
@ -127,12 +139,12 @@ static AXG_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL);
|
|||
static AXG_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL);
|
||||
static AXG_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL);
|
||||
static AXG_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL);
|
||||
static AXG_MST_MCLK_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
|
||||
static AXG_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0);
|
||||
static AXG_MST_MCLK_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1);
|
||||
static AXG_MST_SYS_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL);
|
||||
static AXG_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1);
|
||||
|
||||
#define AXG_MST_MCLK_GATE(_name, _reg) \
|
||||
AXG_AUD_GATE(_name, _reg, 31, "axg_"#_name"_div", \
|
||||
#define AXG_MST_MCLK_GATE(_name, _reg) \
|
||||
AXG_AUD_GATE(_name, _reg, 31, "axg_"#_name"_div", \
|
||||
CLK_SET_RATE_PARENT)
|
||||
|
||||
static AXG_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL);
|
||||
|
|
|
@ -22,8 +22,13 @@
|
|||
|
||||
static DEFINE_SPINLOCK(meson_clk_lock);
|
||||
|
||||
static struct clk_regmap axg_fixed_pll = {
|
||||
static struct clk_regmap axg_fixed_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 0,
|
||||
|
@ -34,11 +39,6 @@ static struct clk_regmap axg_fixed_pll = {
|
|||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.frac = {
|
||||
.reg_off = HHI_MPLL_CNTL2,
|
||||
.shift = 0,
|
||||
|
@ -56,15 +56,39 @@ static struct clk_regmap axg_fixed_pll = {
|
|||
},
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fixed_pll",
|
||||
.name = "fixed_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap axg_sys_pll = {
|
||||
static struct clk_regmap axg_fixed_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_MPLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fixed_pll",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll_dco" },
|
||||
.num_parents = 1,
|
||||
/*
|
||||
* This clock won't ever change at runtime so
|
||||
* CLK_SET_RATE_PARENT is not required
|
||||
*/
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap axg_sys_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 0,
|
||||
|
@ -75,11 +99,6 @@ static struct clk_regmap axg_sys_pll = {
|
|||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.l = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 31,
|
||||
|
@ -92,102 +111,59 @@ static struct clk_regmap axg_sys_pll = {
|
|||
},
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sys_pll",
|
||||
.name = "sys_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct pll_rate_table axg_gp0_pll_rate_table[] = {
|
||||
PLL_RATE(240000000, 40, 1, 2),
|
||||
PLL_RATE(246000000, 41, 1, 2),
|
||||
PLL_RATE(252000000, 42, 1, 2),
|
||||
PLL_RATE(258000000, 43, 1, 2),
|
||||
PLL_RATE(264000000, 44, 1, 2),
|
||||
PLL_RATE(270000000, 45, 1, 2),
|
||||
PLL_RATE(276000000, 46, 1, 2),
|
||||
PLL_RATE(282000000, 47, 1, 2),
|
||||
PLL_RATE(288000000, 48, 1, 2),
|
||||
PLL_RATE(294000000, 49, 1, 2),
|
||||
PLL_RATE(300000000, 50, 1, 2),
|
||||
PLL_RATE(306000000, 51, 1, 2),
|
||||
PLL_RATE(312000000, 52, 1, 2),
|
||||
PLL_RATE(318000000, 53, 1, 2),
|
||||
PLL_RATE(324000000, 54, 1, 2),
|
||||
PLL_RATE(330000000, 55, 1, 2),
|
||||
PLL_RATE(336000000, 56, 1, 2),
|
||||
PLL_RATE(342000000, 57, 1, 2),
|
||||
PLL_RATE(348000000, 58, 1, 2),
|
||||
PLL_RATE(354000000, 59, 1, 2),
|
||||
PLL_RATE(360000000, 60, 1, 2),
|
||||
PLL_RATE(366000000, 61, 1, 2),
|
||||
PLL_RATE(372000000, 62, 1, 2),
|
||||
PLL_RATE(378000000, 63, 1, 2),
|
||||
PLL_RATE(384000000, 64, 1, 2),
|
||||
PLL_RATE(390000000, 65, 1, 3),
|
||||
PLL_RATE(396000000, 66, 1, 3),
|
||||
PLL_RATE(402000000, 67, 1, 3),
|
||||
PLL_RATE(408000000, 68, 1, 3),
|
||||
PLL_RATE(480000000, 40, 1, 1),
|
||||
PLL_RATE(492000000, 41, 1, 1),
|
||||
PLL_RATE(504000000, 42, 1, 1),
|
||||
PLL_RATE(516000000, 43, 1, 1),
|
||||
PLL_RATE(528000000, 44, 1, 1),
|
||||
PLL_RATE(540000000, 45, 1, 1),
|
||||
PLL_RATE(552000000, 46, 1, 1),
|
||||
PLL_RATE(564000000, 47, 1, 1),
|
||||
PLL_RATE(576000000, 48, 1, 1),
|
||||
PLL_RATE(588000000, 49, 1, 1),
|
||||
PLL_RATE(600000000, 50, 1, 1),
|
||||
PLL_RATE(612000000, 51, 1, 1),
|
||||
PLL_RATE(624000000, 52, 1, 1),
|
||||
PLL_RATE(636000000, 53, 1, 1),
|
||||
PLL_RATE(648000000, 54, 1, 1),
|
||||
PLL_RATE(660000000, 55, 1, 1),
|
||||
PLL_RATE(672000000, 56, 1, 1),
|
||||
PLL_RATE(684000000, 57, 1, 1),
|
||||
PLL_RATE(696000000, 58, 1, 1),
|
||||
PLL_RATE(708000000, 59, 1, 1),
|
||||
PLL_RATE(720000000, 60, 1, 1),
|
||||
PLL_RATE(732000000, 61, 1, 1),
|
||||
PLL_RATE(744000000, 62, 1, 1),
|
||||
PLL_RATE(756000000, 63, 1, 1),
|
||||
PLL_RATE(768000000, 64, 1, 1),
|
||||
PLL_RATE(780000000, 65, 1, 1),
|
||||
PLL_RATE(792000000, 66, 1, 1),
|
||||
PLL_RATE(804000000, 67, 1, 1),
|
||||
PLL_RATE(816000000, 68, 1, 1),
|
||||
PLL_RATE(960000000, 40, 1, 0),
|
||||
PLL_RATE(984000000, 41, 1, 0),
|
||||
PLL_RATE(1008000000, 42, 1, 0),
|
||||
PLL_RATE(1032000000, 43, 1, 0),
|
||||
PLL_RATE(1056000000, 44, 1, 0),
|
||||
PLL_RATE(1080000000, 45, 1, 0),
|
||||
PLL_RATE(1104000000, 46, 1, 0),
|
||||
PLL_RATE(1128000000, 47, 1, 0),
|
||||
PLL_RATE(1152000000, 48, 1, 0),
|
||||
PLL_RATE(1176000000, 49, 1, 0),
|
||||
PLL_RATE(1200000000, 50, 1, 0),
|
||||
PLL_RATE(1224000000, 51, 1, 0),
|
||||
PLL_RATE(1248000000, 52, 1, 0),
|
||||
PLL_RATE(1272000000, 53, 1, 0),
|
||||
PLL_RATE(1296000000, 54, 1, 0),
|
||||
PLL_RATE(1320000000, 55, 1, 0),
|
||||
PLL_RATE(1344000000, 56, 1, 0),
|
||||
PLL_RATE(1368000000, 57, 1, 0),
|
||||
PLL_RATE(1392000000, 58, 1, 0),
|
||||
PLL_RATE(1416000000, 59, 1, 0),
|
||||
PLL_RATE(1440000000, 60, 1, 0),
|
||||
PLL_RATE(1464000000, 61, 1, 0),
|
||||
PLL_RATE(1488000000, 62, 1, 0),
|
||||
PLL_RATE(1512000000, 63, 1, 0),
|
||||
PLL_RATE(1536000000, 64, 1, 0),
|
||||
PLL_RATE(1560000000, 65, 1, 0),
|
||||
PLL_RATE(1584000000, 66, 1, 0),
|
||||
PLL_RATE(1608000000, 67, 1, 0),
|
||||
PLL_RATE(1632000000, 68, 1, 0),
|
||||
static struct clk_regmap axg_sys_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_SYS_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sys_pll",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "sys_pll_dco" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct pll_params_table axg_gp0_pll_params_table[] = {
|
||||
PLL_PARAMS(40, 1),
|
||||
PLL_PARAMS(41, 1),
|
||||
PLL_PARAMS(42, 1),
|
||||
PLL_PARAMS(43, 1),
|
||||
PLL_PARAMS(44, 1),
|
||||
PLL_PARAMS(45, 1),
|
||||
PLL_PARAMS(46, 1),
|
||||
PLL_PARAMS(47, 1),
|
||||
PLL_PARAMS(48, 1),
|
||||
PLL_PARAMS(49, 1),
|
||||
PLL_PARAMS(50, 1),
|
||||
PLL_PARAMS(51, 1),
|
||||
PLL_PARAMS(52, 1),
|
||||
PLL_PARAMS(53, 1),
|
||||
PLL_PARAMS(54, 1),
|
||||
PLL_PARAMS(55, 1),
|
||||
PLL_PARAMS(56, 1),
|
||||
PLL_PARAMS(57, 1),
|
||||
PLL_PARAMS(58, 1),
|
||||
PLL_PARAMS(59, 1),
|
||||
PLL_PARAMS(60, 1),
|
||||
PLL_PARAMS(61, 1),
|
||||
PLL_PARAMS(62, 1),
|
||||
PLL_PARAMS(63, 1),
|
||||
PLL_PARAMS(64, 1),
|
||||
PLL_PARAMS(65, 1),
|
||||
PLL_PARAMS(66, 1),
|
||||
PLL_PARAMS(67, 1),
|
||||
PLL_PARAMS(68, 1),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
@ -197,11 +173,15 @@ static const struct reg_sequence axg_gp0_init_regs[] = {
|
|||
{ .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 },
|
||||
{ .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d },
|
||||
{ .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 },
|
||||
{ .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 },
|
||||
};
|
||||
|
||||
static struct clk_regmap axg_gp0_pll = {
|
||||
static struct clk_regmap axg_gp0_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 0,
|
||||
|
@ -212,11 +192,6 @@ static struct clk_regmap axg_gp0_pll = {
|
|||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.frac = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL1,
|
||||
.shift = 0,
|
||||
|
@ -232,29 +207,49 @@ static struct clk_regmap axg_gp0_pll = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = axg_gp0_pll_rate_table,
|
||||
.table = axg_gp0_pll_params_table,
|
||||
.init_regs = axg_gp0_init_regs,
|
||||
.init_count = ARRAY_SIZE(axg_gp0_init_regs),
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gp0_pll",
|
||||
.name = "gp0_pll_dco",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap axg_gp0_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_GP0_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gp0_pll",
|
||||
.ops = &clk_regmap_divider_ops,
|
||||
.parent_names = (const char *[]){ "gp0_pll_dco" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct reg_sequence axg_hifi_init_regs[] = {
|
||||
{ .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 },
|
||||
{ .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be },
|
||||
{ .reg = HHI_HIFI_PLL_CNTL3, .def = 0x0a6a3a88 },
|
||||
{ .reg = HHI_HIFI_PLL_CNTL4, .def = 0xc000004d },
|
||||
{ .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 },
|
||||
{ .reg = HHI_HIFI_PLL_CNTL, .def = 0x40010250 },
|
||||
};
|
||||
|
||||
static struct clk_regmap axg_hifi_pll = {
|
||||
static struct clk_regmap axg_hifi_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_HIFI_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_HIFI_PLL_CNTL,
|
||||
.shift = 0,
|
||||
|
@ -265,11 +260,6 @@ static struct clk_regmap axg_hifi_pll = {
|
|||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_HIFI_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.frac = {
|
||||
.reg_off = HHI_HIFI_PLL_CNTL5,
|
||||
.shift = 0,
|
||||
|
@ -285,19 +275,35 @@ static struct clk_regmap axg_hifi_pll = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = axg_gp0_pll_rate_table,
|
||||
.table = axg_gp0_pll_params_table,
|
||||
.init_regs = axg_hifi_init_regs,
|
||||
.init_count = ARRAY_SIZE(axg_hifi_init_regs),
|
||||
.flags = CLK_MESON_PLL_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hifi_pll",
|
||||
.name = "hifi_pll_dco",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap axg_hifi_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_HIFI_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hifi_pll",
|
||||
.ops = &clk_regmap_divider_ops,
|
||||
.parent_names = (const char *[]){ "hifi_pll_dco" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor axg_fclk_div2_div = {
|
||||
.mult = 1,
|
||||
.div = 2,
|
||||
|
@ -625,29 +631,31 @@ static struct clk_regmap axg_mpll3 = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct pll_rate_table axg_pcie_pll_rate_table[] = {
|
||||
static const struct pll_params_table axg_pcie_pll_params_table[] = {
|
||||
{
|
||||
.rate = 100000000,
|
||||
.m = 200,
|
||||
.n = 3,
|
||||
.od = 1,
|
||||
.od2 = 3,
|
||||
.m = 200,
|
||||
.n = 3,
|
||||
},
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static const struct reg_sequence axg_pcie_init_regs[] = {
|
||||
{ .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 },
|
||||
{ .reg = HHI_PCIE_PLL_CNTL1, .def = 0x0084a2aa },
|
||||
{ .reg = HHI_PCIE_PLL_CNTL2, .def = 0xb75020be },
|
||||
{ .reg = HHI_PCIE_PLL_CNTL3, .def = 0x0a47488e },
|
||||
{ .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d },
|
||||
{ .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 },
|
||||
{ .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 },
|
||||
{ .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 },
|
||||
};
|
||||
|
||||
static struct clk_regmap axg_pcie_pll = {
|
||||
static struct clk_regmap axg_pcie_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_PCIE_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_PCIE_PLL_CNTL,
|
||||
.shift = 0,
|
||||
|
@ -658,16 +666,6 @@ static struct clk_regmap axg_pcie_pll = {
|
|||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_PCIE_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.od2 = {
|
||||
.reg_off = HHI_PCIE_PLL_CNTL6,
|
||||
.shift = 6,
|
||||
.width = 2,
|
||||
},
|
||||
.frac = {
|
||||
.reg_off = HHI_PCIE_PLL_CNTL1,
|
||||
.shift = 0,
|
||||
|
@ -683,29 +681,63 @@ static struct clk_regmap axg_pcie_pll = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = axg_pcie_pll_rate_table,
|
||||
.table = axg_pcie_pll_params_table,
|
||||
.init_regs = axg_pcie_init_regs,
|
||||
.init_count = ARRAY_SIZE(axg_pcie_init_regs),
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_pll",
|
||||
.name = "pcie_pll_dco",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap axg_pcie_pll_od = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_PCIE_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_pll_od",
|
||||
.ops = &clk_regmap_divider_ops,
|
||||
.parent_names = (const char *[]){ "pcie_pll_dco" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap axg_pcie_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_PCIE_PLL_CNTL6,
|
||||
.shift = 6,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_pll",
|
||||
.ops = &clk_regmap_divider_ops,
|
||||
.parent_names = (const char *[]){ "pcie_pll_od" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap axg_pcie_mux = {
|
||||
.data = &(struct clk_regmap_mux_data){
|
||||
.offset = HHI_PCIE_PLL_CNTL6,
|
||||
.mask = 0x1,
|
||||
.shift = 2,
|
||||
/* skip the parent mpll3, reserved for debug */
|
||||
.table = (u32[]){ 1 },
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcie_mux",
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_names = (const char *[]){ "mpll3", "pcie_pll" },
|
||||
.num_parents = 2,
|
||||
.parent_names = (const char *[]){ "pcie_pll" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
@ -1107,6 +1139,12 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
|
|||
[CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw,
|
||||
[CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw,
|
||||
[CLKID_GEN_CLK] = &axg_gen_clk.hw,
|
||||
[CLKID_SYS_PLL_DCO] = &axg_sys_pll_dco.hw,
|
||||
[CLKID_FIXED_PLL_DCO] = &axg_fixed_pll_dco.hw,
|
||||
[CLKID_GP0_PLL_DCO] = &axg_gp0_pll_dco.hw,
|
||||
[CLKID_HIFI_PLL_DCO] = &axg_hifi_pll_dco.hw,
|
||||
[CLKID_PCIE_PLL_DCO] = &axg_pcie_pll_dco.hw,
|
||||
[CLKID_PCIE_PLL_OD] = &axg_pcie_pll_od.hw,
|
||||
[NR_CLKS] = NULL,
|
||||
},
|
||||
.num = NR_CLKS,
|
||||
|
@ -1185,6 +1223,8 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
|
|||
&axg_fclk_div4,
|
||||
&axg_fclk_div5,
|
||||
&axg_fclk_div7,
|
||||
&axg_pcie_pll_dco,
|
||||
&axg_pcie_pll_od,
|
||||
&axg_pcie_pll,
|
||||
&axg_pcie_mux,
|
||||
&axg_pcie_ref,
|
||||
|
@ -1194,6 +1234,12 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
|
|||
&axg_gen_clk_sel,
|
||||
&axg_gen_clk_div,
|
||||
&axg_gen_clk,
|
||||
&axg_fixed_pll_dco,
|
||||
&axg_sys_pll_dco,
|
||||
&axg_gp0_pll_dco,
|
||||
&axg_hifi_pll_dco,
|
||||
&axg_pcie_pll_dco,
|
||||
&axg_pcie_pll_od,
|
||||
};
|
||||
|
||||
static const struct of_device_id clkc_match_table[] = {
|
||||
|
|
|
@ -133,8 +133,14 @@
|
|||
#define CLKID_PCIE_REF 78
|
||||
#define CLKID_GEN_CLK_SEL 82
|
||||
#define CLKID_GEN_CLK_DIV 83
|
||||
#define CLKID_SYS_PLL_DCO 85
|
||||
#define CLKID_FIXED_PLL_DCO 86
|
||||
#define CLKID_GP0_PLL_DCO 87
|
||||
#define CLKID_HIFI_PLL_DCO 88
|
||||
#define CLKID_PCIE_PLL_DCO 89
|
||||
#define CLKID_PCIE_PLL_OD 90
|
||||
|
||||
#define NR_CLKS 85
|
||||
#define NR_CLKS 91
|
||||
|
||||
/* include the CLKIDs that have been made part of the DT binding */
|
||||
#include <dt-bindings/clock/axg-clkc.h>
|
||||
|
|
|
@ -11,15 +11,19 @@
|
|||
* In the most basic form, a Meson PLL is composed as follows:
|
||||
*
|
||||
* PLL
|
||||
* +------------------------------+
|
||||
* | |
|
||||
* in -----[ /N ]---[ *M ]---[ >>OD ]----->> out
|
||||
* | ^ ^ |
|
||||
* +------------------------------+
|
||||
* | |
|
||||
* FREF VCO
|
||||
* +--------------------------------+
|
||||
* | |
|
||||
* | +--+ |
|
||||
* in >>-----[ /N ]--->| | +-----+ |
|
||||
* | | |------| DCO |---->> out
|
||||
* | +--------->| | +--v--+ |
|
||||
* | | +--+ | |
|
||||
* | | | |
|
||||
* | +--[ *(M + (F/Fmax) ]<--+ |
|
||||
* | |
|
||||
* +--------------------------------+
|
||||
*
|
||||
* out = in * (m + frac / frac_max) / (n << sum(ods))
|
||||
* out = in * (m + frac / frac_max) / n
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
@ -41,12 +45,11 @@ meson_clk_pll_data(struct clk_regmap *clk)
|
|||
}
|
||||
|
||||
static unsigned long __pll_params_to_rate(unsigned long parent_rate,
|
||||
const struct pll_rate_table *pllt,
|
||||
const struct pll_params_table *pllt,
|
||||
u16 frac,
|
||||
struct meson_clk_pll_data *pll)
|
||||
{
|
||||
u64 rate = (u64)parent_rate * pllt->m;
|
||||
unsigned int od = pllt->od + pllt->od2 + pllt->od3;
|
||||
|
||||
if (frac && MESON_PARM_APPLICABLE(&pll->frac)) {
|
||||
u64 frac_rate = (u64)parent_rate * frac;
|
||||
|
@ -55,7 +58,7 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate,
|
|||
(1 << pll->frac.width));
|
||||
}
|
||||
|
||||
return DIV_ROUND_UP_ULL(rate, pllt->n << od);
|
||||
return DIV_ROUND_UP_ULL(rate, pllt->n);
|
||||
}
|
||||
|
||||
static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
|
||||
|
@ -63,20 +66,11 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
|
|||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
struct pll_rate_table pllt;
|
||||
struct pll_params_table pllt;
|
||||
u16 frac;
|
||||
|
||||
pllt.n = meson_parm_read(clk->map, &pll->n);
|
||||
pllt.m = meson_parm_read(clk->map, &pll->m);
|
||||
pllt.od = meson_parm_read(clk->map, &pll->od);
|
||||
|
||||
pllt.od2 = MESON_PARM_APPLICABLE(&pll->od2) ?
|
||||
meson_parm_read(clk->map, &pll->od2) :
|
||||
0;
|
||||
|
||||
pllt.od3 = MESON_PARM_APPLICABLE(&pll->od3) ?
|
||||
meson_parm_read(clk->map, &pll->od3) :
|
||||
0;
|
||||
|
||||
frac = MESON_PARM_APPLICABLE(&pll->frac) ?
|
||||
meson_parm_read(clk->map, &pll->frac) :
|
||||
|
@ -87,14 +81,12 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
|
|||
|
||||
static u16 __pll_params_with_frac(unsigned long rate,
|
||||
unsigned long parent_rate,
|
||||
const struct pll_rate_table *pllt,
|
||||
const struct pll_params_table *pllt,
|
||||
struct meson_clk_pll_data *pll)
|
||||
{
|
||||
u16 frac_max = (1 << pll->frac.width);
|
||||
u64 val = (u64)rate * pllt->n;
|
||||
|
||||
val <<= pllt->od + pllt->od2 + pllt->od3;
|
||||
|
||||
if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST)
|
||||
val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate);
|
||||
else
|
||||
|
@ -105,29 +97,50 @@ static u16 __pll_params_with_frac(unsigned long rate,
|
|||
return min((u16)val, (u16)(frac_max - 1));
|
||||
}
|
||||
|
||||
static const struct pll_rate_table *
|
||||
static bool meson_clk_pll_is_better(unsigned long rate,
|
||||
unsigned long best,
|
||||
unsigned long now,
|
||||
struct meson_clk_pll_data *pll)
|
||||
{
|
||||
if (!(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) ||
|
||||
MESON_PARM_APPLICABLE(&pll->frac)) {
|
||||
/* Round down */
|
||||
if (now < rate && best < now)
|
||||
return true;
|
||||
} else {
|
||||
/* Round Closest */
|
||||
if (abs(now - rate) < abs(best - rate))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct pll_params_table *
|
||||
meson_clk_get_pll_settings(unsigned long rate,
|
||||
unsigned long parent_rate,
|
||||
struct meson_clk_pll_data *pll)
|
||||
{
|
||||
const struct pll_rate_table *table = pll->table;
|
||||
unsigned int i = 0;
|
||||
const struct pll_params_table *table = pll->table;
|
||||
unsigned long best = 0, now = 0;
|
||||
unsigned int i, best_i = 0;
|
||||
|
||||
if (!table)
|
||||
return NULL;
|
||||
|
||||
/* Find the first table element exceeding rate */
|
||||
while (table[i].rate && table[i].rate <= rate)
|
||||
i++;
|
||||
for (i = 0; table[i].n; i++) {
|
||||
now = __pll_params_to_rate(parent_rate, &table[i], 0, pll);
|
||||
|
||||
if (i != 0) {
|
||||
if (MESON_PARM_APPLICABLE(&pll->frac) ||
|
||||
!(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) ||
|
||||
(abs(rate - table[i - 1].rate) <
|
||||
abs(rate - table[i].rate)))
|
||||
i--;
|
||||
/* If we get an exact match, don't bother any further */
|
||||
if (now == rate) {
|
||||
return &table[i];
|
||||
} else if (meson_clk_pll_is_better(rate, best, now, pll)) {
|
||||
best = now;
|
||||
best_i = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (struct pll_rate_table *)&table[i];
|
||||
return (struct pll_params_table *)&table[best_i];
|
||||
}
|
||||
|
||||
static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
@ -135,16 +148,18 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
const struct pll_rate_table *pllt =
|
||||
meson_clk_get_pll_settings(rate, pll);
|
||||
const struct pll_params_table *pllt =
|
||||
meson_clk_get_pll_settings(rate, *parent_rate, pll);
|
||||
unsigned long round;
|
||||
u16 frac;
|
||||
|
||||
if (!pllt)
|
||||
return meson_clk_pll_recalc_rate(hw, *parent_rate);
|
||||
|
||||
if (!MESON_PARM_APPLICABLE(&pll->frac)
|
||||
|| rate == pllt->rate)
|
||||
return pllt->rate;
|
||||
round = __pll_params_to_rate(*parent_rate, pllt, 0, pll);
|
||||
|
||||
if (!MESON_PARM_APPLICABLE(&pll->frac) || rate == round)
|
||||
return round;
|
||||
|
||||
/*
|
||||
* The rate provided by the setting is not an exact match, let's
|
||||
|
@ -185,12 +200,45 @@ static void meson_clk_pll_init(struct clk_hw *hw)
|
|||
}
|
||||
}
|
||||
|
||||
static int meson_clk_pll_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
|
||||
/* Make sure the pll is in reset */
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
|
||||
/* Enable the pll */
|
||||
meson_parm_write(clk->map, &pll->en, 1);
|
||||
|
||||
/* Take the pll out reset */
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
|
||||
if (meson_clk_pll_wait_lock(hw))
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void meson_clk_pll_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
|
||||
/* Put the pll is in reset */
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
|
||||
/* Disable the pll */
|
||||
meson_parm_write(clk->map, &pll->en, 0);
|
||||
}
|
||||
|
||||
static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
const struct pll_rate_table *pllt;
|
||||
const struct pll_params_table *pllt;
|
||||
unsigned int enabled;
|
||||
unsigned long old_rate;
|
||||
u16 frac = 0;
|
||||
|
||||
|
@ -199,32 +247,28 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
|
||||
old_rate = rate;
|
||||
|
||||
pllt = meson_clk_get_pll_settings(rate, pll);
|
||||
pllt = meson_clk_get_pll_settings(rate, parent_rate, pll);
|
||||
if (!pllt)
|
||||
return -EINVAL;
|
||||
|
||||
/* Put the pll in reset to write the params */
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
enabled = meson_parm_read(clk->map, &pll->en);
|
||||
if (enabled)
|
||||
meson_clk_pll_disable(hw);
|
||||
|
||||
meson_parm_write(clk->map, &pll->n, pllt->n);
|
||||
meson_parm_write(clk->map, &pll->m, pllt->m);
|
||||
meson_parm_write(clk->map, &pll->od, pllt->od);
|
||||
|
||||
if (MESON_PARM_APPLICABLE(&pll->od2))
|
||||
meson_parm_write(clk->map, &pll->od2, pllt->od2);
|
||||
|
||||
if (MESON_PARM_APPLICABLE(&pll->od3))
|
||||
meson_parm_write(clk->map, &pll->od3, pllt->od3);
|
||||
|
||||
if (MESON_PARM_APPLICABLE(&pll->frac)) {
|
||||
frac = __pll_params_with_frac(rate, parent_rate, pllt, pll);
|
||||
meson_parm_write(clk->map, &pll->frac, frac);
|
||||
}
|
||||
|
||||
/* make sure the reset is cleared at this point */
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
/* If the pll is stopped, bail out now */
|
||||
if (!enabled)
|
||||
return 0;
|
||||
|
||||
if (meson_clk_pll_wait_lock(hw)) {
|
||||
if (meson_clk_pll_enable(hw)) {
|
||||
pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
|
||||
__func__, old_rate);
|
||||
/*
|
||||
|
@ -244,6 +288,8 @@ const struct clk_ops meson_clk_pll_ops = {
|
|||
.recalc_rate = meson_clk_pll_recalc_rate,
|
||||
.round_rate = meson_clk_pll_round_rate,
|
||||
.set_rate = meson_clk_pll_set_rate,
|
||||
.enable = meson_clk_pll_enable,
|
||||
.disable = meson_clk_pll_disable
|
||||
};
|
||||
|
||||
const struct clk_ops meson_clk_pll_ro_ops = {
|
||||
|
|
|
@ -43,37 +43,29 @@ static inline void meson_parm_write(struct regmap *map, struct parm *p,
|
|||
}
|
||||
|
||||
|
||||
struct pll_rate_table {
|
||||
unsigned long rate;
|
||||
struct pll_params_table {
|
||||
u16 m;
|
||||
u16 n;
|
||||
u16 od;
|
||||
u16 od2;
|
||||
u16 od3;
|
||||
};
|
||||
|
||||
#define PLL_RATE(_r, _m, _n, _od) \
|
||||
#define PLL_PARAMS(_m, _n) \
|
||||
{ \
|
||||
.rate = (_r), \
|
||||
.m = (_m), \
|
||||
.n = (_n), \
|
||||
.od = (_od), \
|
||||
}
|
||||
|
||||
#define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
|
||||
|
||||
struct meson_clk_pll_data {
|
||||
struct parm en;
|
||||
struct parm m;
|
||||
struct parm n;
|
||||
struct parm frac;
|
||||
struct parm od;
|
||||
struct parm od2;
|
||||
struct parm od3;
|
||||
struct parm l;
|
||||
struct parm rst;
|
||||
const struct reg_sequence *init_regs;
|
||||
unsigned int init_count;
|
||||
const struct pll_rate_table *table;
|
||||
const struct pll_params_table *table;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
|
|
|
@ -18,165 +18,77 @@
|
|||
|
||||
static DEFINE_SPINLOCK(meson_clk_lock);
|
||||
|
||||
static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = {
|
||||
PLL_RATE(96000000, 32, 1, 3),
|
||||
PLL_RATE(99000000, 33, 1, 3),
|
||||
PLL_RATE(102000000, 34, 1, 3),
|
||||
PLL_RATE(105000000, 35, 1, 3),
|
||||
PLL_RATE(108000000, 36, 1, 3),
|
||||
PLL_RATE(111000000, 37, 1, 3),
|
||||
PLL_RATE(114000000, 38, 1, 3),
|
||||
PLL_RATE(117000000, 39, 1, 3),
|
||||
PLL_RATE(120000000, 40, 1, 3),
|
||||
PLL_RATE(123000000, 41, 1, 3),
|
||||
PLL_RATE(126000000, 42, 1, 3),
|
||||
PLL_RATE(129000000, 43, 1, 3),
|
||||
PLL_RATE(132000000, 44, 1, 3),
|
||||
PLL_RATE(135000000, 45, 1, 3),
|
||||
PLL_RATE(138000000, 46, 1, 3),
|
||||
PLL_RATE(141000000, 47, 1, 3),
|
||||
PLL_RATE(144000000, 48, 1, 3),
|
||||
PLL_RATE(147000000, 49, 1, 3),
|
||||
PLL_RATE(150000000, 50, 1, 3),
|
||||
PLL_RATE(153000000, 51, 1, 3),
|
||||
PLL_RATE(156000000, 52, 1, 3),
|
||||
PLL_RATE(159000000, 53, 1, 3),
|
||||
PLL_RATE(162000000, 54, 1, 3),
|
||||
PLL_RATE(165000000, 55, 1, 3),
|
||||
PLL_RATE(168000000, 56, 1, 3),
|
||||
PLL_RATE(171000000, 57, 1, 3),
|
||||
PLL_RATE(174000000, 58, 1, 3),
|
||||
PLL_RATE(177000000, 59, 1, 3),
|
||||
PLL_RATE(180000000, 60, 1, 3),
|
||||
PLL_RATE(183000000, 61, 1, 3),
|
||||
PLL_RATE(186000000, 62, 1, 3),
|
||||
PLL_RATE(192000000, 32, 1, 2),
|
||||
PLL_RATE(198000000, 33, 1, 2),
|
||||
PLL_RATE(204000000, 34, 1, 2),
|
||||
PLL_RATE(210000000, 35, 1, 2),
|
||||
PLL_RATE(216000000, 36, 1, 2),
|
||||
PLL_RATE(222000000, 37, 1, 2),
|
||||
PLL_RATE(228000000, 38, 1, 2),
|
||||
PLL_RATE(234000000, 39, 1, 2),
|
||||
PLL_RATE(240000000, 40, 1, 2),
|
||||
PLL_RATE(246000000, 41, 1, 2),
|
||||
PLL_RATE(252000000, 42, 1, 2),
|
||||
PLL_RATE(258000000, 43, 1, 2),
|
||||
PLL_RATE(264000000, 44, 1, 2),
|
||||
PLL_RATE(270000000, 45, 1, 2),
|
||||
PLL_RATE(276000000, 46, 1, 2),
|
||||
PLL_RATE(282000000, 47, 1, 2),
|
||||
PLL_RATE(288000000, 48, 1, 2),
|
||||
PLL_RATE(294000000, 49, 1, 2),
|
||||
PLL_RATE(300000000, 50, 1, 2),
|
||||
PLL_RATE(306000000, 51, 1, 2),
|
||||
PLL_RATE(312000000, 52, 1, 2),
|
||||
PLL_RATE(318000000, 53, 1, 2),
|
||||
PLL_RATE(324000000, 54, 1, 2),
|
||||
PLL_RATE(330000000, 55, 1, 2),
|
||||
PLL_RATE(336000000, 56, 1, 2),
|
||||
PLL_RATE(342000000, 57, 1, 2),
|
||||
PLL_RATE(348000000, 58, 1, 2),
|
||||
PLL_RATE(354000000, 59, 1, 2),
|
||||
PLL_RATE(360000000, 60, 1, 2),
|
||||
PLL_RATE(366000000, 61, 1, 2),
|
||||
PLL_RATE(372000000, 62, 1, 2),
|
||||
PLL_RATE(384000000, 32, 1, 1),
|
||||
PLL_RATE(396000000, 33, 1, 1),
|
||||
PLL_RATE(408000000, 34, 1, 1),
|
||||
PLL_RATE(420000000, 35, 1, 1),
|
||||
PLL_RATE(432000000, 36, 1, 1),
|
||||
PLL_RATE(444000000, 37, 1, 1),
|
||||
PLL_RATE(456000000, 38, 1, 1),
|
||||
PLL_RATE(468000000, 39, 1, 1),
|
||||
PLL_RATE(480000000, 40, 1, 1),
|
||||
PLL_RATE(492000000, 41, 1, 1),
|
||||
PLL_RATE(504000000, 42, 1, 1),
|
||||
PLL_RATE(516000000, 43, 1, 1),
|
||||
PLL_RATE(528000000, 44, 1, 1),
|
||||
PLL_RATE(540000000, 45, 1, 1),
|
||||
PLL_RATE(552000000, 46, 1, 1),
|
||||
PLL_RATE(564000000, 47, 1, 1),
|
||||
PLL_RATE(576000000, 48, 1, 1),
|
||||
PLL_RATE(588000000, 49, 1, 1),
|
||||
PLL_RATE(600000000, 50, 1, 1),
|
||||
PLL_RATE(612000000, 51, 1, 1),
|
||||
PLL_RATE(624000000, 52, 1, 1),
|
||||
PLL_RATE(636000000, 53, 1, 1),
|
||||
PLL_RATE(648000000, 54, 1, 1),
|
||||
PLL_RATE(660000000, 55, 1, 1),
|
||||
PLL_RATE(672000000, 56, 1, 1),
|
||||
PLL_RATE(684000000, 57, 1, 1),
|
||||
PLL_RATE(696000000, 58, 1, 1),
|
||||
PLL_RATE(708000000, 59, 1, 1),
|
||||
PLL_RATE(720000000, 60, 1, 1),
|
||||
PLL_RATE(732000000, 61, 1, 1),
|
||||
PLL_RATE(744000000, 62, 1, 1),
|
||||
PLL_RATE(768000000, 32, 1, 0),
|
||||
PLL_RATE(792000000, 33, 1, 0),
|
||||
PLL_RATE(816000000, 34, 1, 0),
|
||||
PLL_RATE(840000000, 35, 1, 0),
|
||||
PLL_RATE(864000000, 36, 1, 0),
|
||||
PLL_RATE(888000000, 37, 1, 0),
|
||||
PLL_RATE(912000000, 38, 1, 0),
|
||||
PLL_RATE(936000000, 39, 1, 0),
|
||||
PLL_RATE(960000000, 40, 1, 0),
|
||||
PLL_RATE(984000000, 41, 1, 0),
|
||||
PLL_RATE(1008000000, 42, 1, 0),
|
||||
PLL_RATE(1032000000, 43, 1, 0),
|
||||
PLL_RATE(1056000000, 44, 1, 0),
|
||||
PLL_RATE(1080000000, 45, 1, 0),
|
||||
PLL_RATE(1104000000, 46, 1, 0),
|
||||
PLL_RATE(1128000000, 47, 1, 0),
|
||||
PLL_RATE(1152000000, 48, 1, 0),
|
||||
PLL_RATE(1176000000, 49, 1, 0),
|
||||
PLL_RATE(1200000000, 50, 1, 0),
|
||||
PLL_RATE(1224000000, 51, 1, 0),
|
||||
PLL_RATE(1248000000, 52, 1, 0),
|
||||
PLL_RATE(1272000000, 53, 1, 0),
|
||||
PLL_RATE(1296000000, 54, 1, 0),
|
||||
PLL_RATE(1320000000, 55, 1, 0),
|
||||
PLL_RATE(1344000000, 56, 1, 0),
|
||||
PLL_RATE(1368000000, 57, 1, 0),
|
||||
PLL_RATE(1392000000, 58, 1, 0),
|
||||
PLL_RATE(1416000000, 59, 1, 0),
|
||||
PLL_RATE(1440000000, 60, 1, 0),
|
||||
PLL_RATE(1464000000, 61, 1, 0),
|
||||
PLL_RATE(1488000000, 62, 1, 0),
|
||||
static const struct pll_params_table gxbb_gp0_pll_params_table[] = {
|
||||
PLL_PARAMS(32, 1),
|
||||
PLL_PARAMS(33, 1),
|
||||
PLL_PARAMS(34, 1),
|
||||
PLL_PARAMS(35, 1),
|
||||
PLL_PARAMS(36, 1),
|
||||
PLL_PARAMS(37, 1),
|
||||
PLL_PARAMS(38, 1),
|
||||
PLL_PARAMS(39, 1),
|
||||
PLL_PARAMS(40, 1),
|
||||
PLL_PARAMS(41, 1),
|
||||
PLL_PARAMS(42, 1),
|
||||
PLL_PARAMS(43, 1),
|
||||
PLL_PARAMS(44, 1),
|
||||
PLL_PARAMS(45, 1),
|
||||
PLL_PARAMS(46, 1),
|
||||
PLL_PARAMS(47, 1),
|
||||
PLL_PARAMS(48, 1),
|
||||
PLL_PARAMS(49, 1),
|
||||
PLL_PARAMS(50, 1),
|
||||
PLL_PARAMS(51, 1),
|
||||
PLL_PARAMS(52, 1),
|
||||
PLL_PARAMS(53, 1),
|
||||
PLL_PARAMS(54, 1),
|
||||
PLL_PARAMS(55, 1),
|
||||
PLL_PARAMS(56, 1),
|
||||
PLL_PARAMS(57, 1),
|
||||
PLL_PARAMS(58, 1),
|
||||
PLL_PARAMS(59, 1),
|
||||
PLL_PARAMS(60, 1),
|
||||
PLL_PARAMS(61, 1),
|
||||
PLL_PARAMS(62, 1),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static const struct pll_rate_table gxl_gp0_pll_rate_table[] = {
|
||||
PLL_RATE(504000000, 42, 1, 1),
|
||||
PLL_RATE(516000000, 43, 1, 1),
|
||||
PLL_RATE(528000000, 44, 1, 1),
|
||||
PLL_RATE(540000000, 45, 1, 1),
|
||||
PLL_RATE(552000000, 46, 1, 1),
|
||||
PLL_RATE(564000000, 47, 1, 1),
|
||||
PLL_RATE(576000000, 48, 1, 1),
|
||||
PLL_RATE(588000000, 49, 1, 1),
|
||||
PLL_RATE(600000000, 50, 1, 1),
|
||||
PLL_RATE(612000000, 51, 1, 1),
|
||||
PLL_RATE(624000000, 52, 1, 1),
|
||||
PLL_RATE(636000000, 53, 1, 1),
|
||||
PLL_RATE(648000000, 54, 1, 1),
|
||||
PLL_RATE(660000000, 55, 1, 1),
|
||||
PLL_RATE(672000000, 56, 1, 1),
|
||||
PLL_RATE(684000000, 57, 1, 1),
|
||||
PLL_RATE(696000000, 58, 1, 1),
|
||||
PLL_RATE(708000000, 59, 1, 1),
|
||||
PLL_RATE(720000000, 60, 1, 1),
|
||||
PLL_RATE(732000000, 61, 1, 1),
|
||||
PLL_RATE(744000000, 62, 1, 1),
|
||||
PLL_RATE(756000000, 63, 1, 1),
|
||||
PLL_RATE(768000000, 64, 1, 1),
|
||||
PLL_RATE(780000000, 65, 1, 1),
|
||||
PLL_RATE(792000000, 66, 1, 1),
|
||||
static const struct pll_params_table gxl_gp0_pll_params_table[] = {
|
||||
PLL_PARAMS(42, 1),
|
||||
PLL_PARAMS(43, 1),
|
||||
PLL_PARAMS(44, 1),
|
||||
PLL_PARAMS(45, 1),
|
||||
PLL_PARAMS(46, 1),
|
||||
PLL_PARAMS(47, 1),
|
||||
PLL_PARAMS(48, 1),
|
||||
PLL_PARAMS(49, 1),
|
||||
PLL_PARAMS(50, 1),
|
||||
PLL_PARAMS(51, 1),
|
||||
PLL_PARAMS(52, 1),
|
||||
PLL_PARAMS(53, 1),
|
||||
PLL_PARAMS(54, 1),
|
||||
PLL_PARAMS(55, 1),
|
||||
PLL_PARAMS(56, 1),
|
||||
PLL_PARAMS(57, 1),
|
||||
PLL_PARAMS(58, 1),
|
||||
PLL_PARAMS(59, 1),
|
||||
PLL_PARAMS(60, 1),
|
||||
PLL_PARAMS(61, 1),
|
||||
PLL_PARAMS(62, 1),
|
||||
PLL_PARAMS(63, 1),
|
||||
PLL_PARAMS(64, 1),
|
||||
PLL_PARAMS(65, 1),
|
||||
PLL_PARAMS(66, 1),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_fixed_pll = {
|
||||
static struct clk_regmap gxbb_fixed_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 0,
|
||||
|
@ -187,11 +99,6 @@ static struct clk_regmap gxbb_fixed_pll = {
|
|||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.frac = {
|
||||
.reg_off = HHI_MPLL_CNTL2,
|
||||
.shift = 0,
|
||||
|
@ -209,11 +116,29 @@ static struct clk_regmap gxbb_fixed_pll = {
|
|||
},
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fixed_pll",
|
||||
.name = "fixed_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_fixed_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_MPLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fixed_pll",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll_dco" },
|
||||
.num_parents = 1,
|
||||
/*
|
||||
* This clock won't ever change at runtime so
|
||||
* CLK_SET_RATE_PARENT is not required
|
||||
*/
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -228,8 +153,13 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_hdmi_pll = {
|
||||
static struct clk_regmap gxbb_hdmi_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL,
|
||||
.shift = 0,
|
||||
|
@ -245,21 +175,6 @@ static struct clk_regmap gxbb_hdmi_pll = {
|
|||
.shift = 0,
|
||||
.width = 12,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL2,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.od2 = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL2,
|
||||
.shift = 22,
|
||||
.width = 2,
|
||||
},
|
||||
.od3 = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL2,
|
||||
.shift = 18,
|
||||
.width = 2,
|
||||
},
|
||||
.l = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL,
|
||||
.shift = 31,
|
||||
|
@ -272,106 +187,163 @@ static struct clk_regmap gxbb_hdmi_pll = {
|
|||
},
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll",
|
||||
.name = "hdmi_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "hdmi_pll_pre_mult" },
|
||||
.num_parents = 1,
|
||||
/*
|
||||
* Display directly handle hdmi pll registers ATM, we need
|
||||
* NOCACHE to keep our view of the clock as accurate as possible
|
||||
*/
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_hdmi_pll_od = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_HDMI_PLL_CNTL2,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll_od",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "hdmi_pll_dco" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_hdmi_pll_od2 = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_HDMI_PLL_CNTL2,
|
||||
.shift = 22,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll_od2",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "hdmi_pll_od" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_hdmi_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_HDMI_PLL_CNTL2,
|
||||
.shift = 18,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "hdmi_pll_od2" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxl_hdmi_pll_od = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_HDMI_PLL_CNTL + 8,
|
||||
.shift = 21,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll_od",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "hdmi_pll_dco" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxl_hdmi_pll_od2 = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_HDMI_PLL_CNTL + 8,
|
||||
.shift = 23,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll_od2",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "hdmi_pll_od" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxl_hdmi_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_HDMI_PLL_CNTL + 8,
|
||||
.shift = 19,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "hdmi_pll_od2" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_sys_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL,
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL,
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.frac = {
|
||||
/*
|
||||
* On gxl, there is a register shift due to
|
||||
* HHI_HDMI_PLL_CNTL1 which does not exist on gxbb,
|
||||
* so we compute the register offset based on the PLL
|
||||
* base to get it right
|
||||
*/
|
||||
.reg_off = HHI_HDMI_PLL_CNTL + 4,
|
||||
.shift = 0,
|
||||
.width = 12,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL + 8,
|
||||
.shift = 21,
|
||||
.width = 2,
|
||||
},
|
||||
.od2 = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL + 8,
|
||||
.shift = 23,
|
||||
.width = 2,
|
||||
},
|
||||
.od3 = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL + 8,
|
||||
.shift = 19,
|
||||
.width = 2,
|
||||
},
|
||||
.l = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL,
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 31,
|
||||
.width = 1,
|
||||
},
|
||||
.rst = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL,
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll",
|
||||
.name = "sys_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_sys_pll = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.m = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 10,
|
||||
.width = 2,
|
||||
},
|
||||
.l = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 31,
|
||||
.width = 1,
|
||||
},
|
||||
.rst = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_SYS_PLL_CNTL,
|
||||
.shift = 10,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sys_pll",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "sys_pll_dco" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -379,11 +351,15 @@ static const struct reg_sequence gxbb_gp0_init_regs[] = {
|
|||
{ .reg = HHI_GP0_PLL_CNTL2, .def = 0x69c80000 },
|
||||
{ .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a5590c4 },
|
||||
{ .reg = HHI_GP0_PLL_CNTL4, .def = 0x0000500d },
|
||||
{ .reg = HHI_GP0_PLL_CNTL, .def = 0x4a000228 },
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_gp0_pll = {
|
||||
static struct clk_regmap gxbb_gp0_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 0,
|
||||
|
@ -394,11 +370,6 @@ static struct clk_regmap gxbb_gp0_pll = {
|
|||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.l = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 31,
|
||||
|
@ -409,16 +380,15 @@ static struct clk_regmap gxbb_gp0_pll = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = gxbb_gp0_pll_rate_table,
|
||||
.table = gxbb_gp0_pll_params_table,
|
||||
.init_regs = gxbb_gp0_init_regs,
|
||||
.init_count = ARRAY_SIZE(gxbb_gp0_init_regs),
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gp0_pll",
|
||||
.name = "gp0_pll_dco",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -428,11 +398,15 @@ static const struct reg_sequence gxl_gp0_init_regs[] = {
|
|||
{ .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 },
|
||||
{ .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d },
|
||||
{ .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 },
|
||||
{ .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 },
|
||||
};
|
||||
|
||||
static struct clk_regmap gxl_gp0_pll = {
|
||||
static struct clk_regmap gxl_gp0_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 0,
|
||||
|
@ -443,11 +417,6 @@ static struct clk_regmap gxl_gp0_pll = {
|
|||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.frac = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL1,
|
||||
.shift = 0,
|
||||
|
@ -463,16 +432,31 @@ static struct clk_regmap gxl_gp0_pll = {
|
|||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = gxl_gp0_pll_rate_table,
|
||||
.table = gxl_gp0_pll_params_table,
|
||||
.init_regs = gxl_gp0_init_regs,
|
||||
.init_count = ARRAY_SIZE(gxl_gp0_init_regs),
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gp0_pll",
|
||||
.name = "gp0_pll_dco",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_gp0_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_GP0_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gp0_pll",
|
||||
.ops = &clk_regmap_divider_ops,
|
||||
.parent_names = (const char *[]){ "gp0_pll_dco" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1933,6 +1917,12 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
|
|||
[CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw,
|
||||
[CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw,
|
||||
[CLKID_GEN_CLK] = &gxbb_gen_clk.hw,
|
||||
[CLKID_FIXED_PLL_DCO] = &gxbb_fixed_pll_dco.hw,
|
||||
[CLKID_HDMI_PLL_DCO] = &gxbb_hdmi_pll_dco.hw,
|
||||
[CLKID_HDMI_PLL_OD] = &gxbb_hdmi_pll_od.hw,
|
||||
[CLKID_HDMI_PLL_OD2] = &gxbb_hdmi_pll_od2.hw,
|
||||
[CLKID_SYS_PLL_DCO] = &gxbb_sys_pll_dco.hw,
|
||||
[CLKID_GP0_PLL_DCO] = &gxbb_gp0_pll_dco.hw,
|
||||
[NR_CLKS] = NULL,
|
||||
},
|
||||
.num = NR_CLKS,
|
||||
|
@ -1948,7 +1938,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
|
|||
[CLKID_FCLK_DIV4] = &gxbb_fclk_div4.hw,
|
||||
[CLKID_FCLK_DIV5] = &gxbb_fclk_div5.hw,
|
||||
[CLKID_FCLK_DIV7] = &gxbb_fclk_div7.hw,
|
||||
[CLKID_GP0_PLL] = &gxl_gp0_pll.hw,
|
||||
[CLKID_GP0_PLL] = &gxbb_gp0_pll.hw,
|
||||
[CLKID_MPEG_SEL] = &gxbb_mpeg_clk_sel.hw,
|
||||
[CLKID_MPEG_DIV] = &gxbb_mpeg_clk_div.hw,
|
||||
[CLKID_CLK81] = &gxbb_clk81.hw,
|
||||
|
@ -2098,19 +2088,29 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
|
|||
[CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw,
|
||||
[CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw,
|
||||
[CLKID_GEN_CLK] = &gxbb_gen_clk.hw,
|
||||
[CLKID_FIXED_PLL_DCO] = &gxbb_fixed_pll_dco.hw,
|
||||
[CLKID_HDMI_PLL_DCO] = &gxbb_hdmi_pll_dco.hw,
|
||||
[CLKID_HDMI_PLL_OD] = &gxl_hdmi_pll_od.hw,
|
||||
[CLKID_HDMI_PLL_OD2] = &gxl_hdmi_pll_od2.hw,
|
||||
[CLKID_SYS_PLL_DCO] = &gxbb_sys_pll_dco.hw,
|
||||
[CLKID_GP0_PLL_DCO] = &gxl_gp0_pll_dco.hw,
|
||||
[NR_CLKS] = NULL,
|
||||
},
|
||||
.num = NR_CLKS,
|
||||
};
|
||||
|
||||
static struct clk_regmap *const gxbb_clk_regmaps[] = {
|
||||
&gxbb_gp0_pll,
|
||||
&gxbb_gp0_pll_dco,
|
||||
&gxbb_hdmi_pll,
|
||||
&gxbb_hdmi_pll_od,
|
||||
&gxbb_hdmi_pll_od2,
|
||||
};
|
||||
|
||||
static struct clk_regmap *const gxl_clk_regmaps[] = {
|
||||
&gxl_gp0_pll,
|
||||
&gxl_gp0_pll_dco,
|
||||
&gxl_hdmi_pll,
|
||||
&gxl_hdmi_pll_od,
|
||||
&gxl_hdmi_pll_od2,
|
||||
};
|
||||
|
||||
static struct clk_regmap *const gx_clk_regmaps[] = {
|
||||
|
@ -2265,6 +2265,10 @@ static struct clk_regmap *const gx_clk_regmaps[] = {
|
|||
&gxbb_gen_clk_sel,
|
||||
&gxbb_gen_clk_div,
|
||||
&gxbb_gen_clk,
|
||||
&gxbb_fixed_pll_dco,
|
||||
&gxbb_hdmi_pll_dco,
|
||||
&gxbb_sys_pll_dco,
|
||||
&gxbb_gp0_pll,
|
||||
};
|
||||
|
||||
struct clkc_data {
|
||||
|
|
|
@ -159,8 +159,14 @@
|
|||
#define CLKID_VDEC_HEVC_DIV 155
|
||||
#define CLKID_GEN_CLK_SEL 157
|
||||
#define CLKID_GEN_CLK_DIV 158
|
||||
#define CLKID_FIXED_PLL_DCO 160
|
||||
#define CLKID_HDMI_PLL_DCO 161
|
||||
#define CLKID_HDMI_PLL_OD 162
|
||||
#define CLKID_HDMI_PLL_OD2 163
|
||||
#define CLKID_SYS_PLL_DCO 164
|
||||
#define CLKID_GP0_PLL_DCO 165
|
||||
|
||||
#define NR_CLKS 160
|
||||
#define NR_CLKS 166
|
||||
|
||||
/* include the CLKIDs that have been made part of the DT binding */
|
||||
#include <dt-bindings/clock/gxbb-clkc.h>
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <linux/clk-provider.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/regmap.h>
|
||||
|
@ -22,66 +21,27 @@
|
|||
|
||||
static DEFINE_SPINLOCK(meson_clk_lock);
|
||||
|
||||
static void __iomem *clk_base;
|
||||
|
||||
struct meson8b_clk_reset {
|
||||
struct reset_controller_dev reset;
|
||||
void __iomem *base;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
static const struct pll_rate_table sys_pll_rate_table[] = {
|
||||
PLL_RATE(312000000, 52, 1, 2),
|
||||
PLL_RATE(336000000, 56, 1, 2),
|
||||
PLL_RATE(360000000, 60, 1, 2),
|
||||
PLL_RATE(384000000, 64, 1, 2),
|
||||
PLL_RATE(408000000, 68, 1, 2),
|
||||
PLL_RATE(432000000, 72, 1, 2),
|
||||
PLL_RATE(456000000, 76, 1, 2),
|
||||
PLL_RATE(480000000, 80, 1, 2),
|
||||
PLL_RATE(504000000, 84, 1, 2),
|
||||
PLL_RATE(528000000, 88, 1, 2),
|
||||
PLL_RATE(552000000, 92, 1, 2),
|
||||
PLL_RATE(576000000, 96, 1, 2),
|
||||
PLL_RATE(600000000, 50, 1, 1),
|
||||
PLL_RATE(624000000, 52, 1, 1),
|
||||
PLL_RATE(648000000, 54, 1, 1),
|
||||
PLL_RATE(672000000, 56, 1, 1),
|
||||
PLL_RATE(696000000, 58, 1, 1),
|
||||
PLL_RATE(720000000, 60, 1, 1),
|
||||
PLL_RATE(744000000, 62, 1, 1),
|
||||
PLL_RATE(768000000, 64, 1, 1),
|
||||
PLL_RATE(792000000, 66, 1, 1),
|
||||
PLL_RATE(816000000, 68, 1, 1),
|
||||
PLL_RATE(840000000, 70, 1, 1),
|
||||
PLL_RATE(864000000, 72, 1, 1),
|
||||
PLL_RATE(888000000, 74, 1, 1),
|
||||
PLL_RATE(912000000, 76, 1, 1),
|
||||
PLL_RATE(936000000, 78, 1, 1),
|
||||
PLL_RATE(960000000, 80, 1, 1),
|
||||
PLL_RATE(984000000, 82, 1, 1),
|
||||
PLL_RATE(1008000000, 84, 1, 1),
|
||||
PLL_RATE(1032000000, 86, 1, 1),
|
||||
PLL_RATE(1056000000, 88, 1, 1),
|
||||
PLL_RATE(1080000000, 90, 1, 1),
|
||||
PLL_RATE(1104000000, 92, 1, 1),
|
||||
PLL_RATE(1128000000, 94, 1, 1),
|
||||
PLL_RATE(1152000000, 96, 1, 1),
|
||||
PLL_RATE(1176000000, 98, 1, 1),
|
||||
PLL_RATE(1200000000, 50, 1, 0),
|
||||
PLL_RATE(1224000000, 51, 1, 0),
|
||||
PLL_RATE(1248000000, 52, 1, 0),
|
||||
PLL_RATE(1272000000, 53, 1, 0),
|
||||
PLL_RATE(1296000000, 54, 1, 0),
|
||||
PLL_RATE(1320000000, 55, 1, 0),
|
||||
PLL_RATE(1344000000, 56, 1, 0),
|
||||
PLL_RATE(1368000000, 57, 1, 0),
|
||||
PLL_RATE(1392000000, 58, 1, 0),
|
||||
PLL_RATE(1416000000, 59, 1, 0),
|
||||
PLL_RATE(1440000000, 60, 1, 0),
|
||||
PLL_RATE(1464000000, 61, 1, 0),
|
||||
PLL_RATE(1488000000, 62, 1, 0),
|
||||
PLL_RATE(1512000000, 63, 1, 0),
|
||||
PLL_RATE(1536000000, 64, 1, 0),
|
||||
static const struct pll_params_table sys_pll_params_table[] = {
|
||||
PLL_PARAMS(50, 1),
|
||||
PLL_PARAMS(51, 1),
|
||||
PLL_PARAMS(52, 1),
|
||||
PLL_PARAMS(53, 1),
|
||||
PLL_PARAMS(54, 1),
|
||||
PLL_PARAMS(55, 1),
|
||||
PLL_PARAMS(56, 1),
|
||||
PLL_PARAMS(57, 1),
|
||||
PLL_PARAMS(58, 1),
|
||||
PLL_PARAMS(59, 1),
|
||||
PLL_PARAMS(60, 1),
|
||||
PLL_PARAMS(61, 1),
|
||||
PLL_PARAMS(62, 1),
|
||||
PLL_PARAMS(63, 1),
|
||||
PLL_PARAMS(64, 1),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
@ -94,8 +54,13 @@ static struct clk_fixed_rate meson8b_xtal = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap meson8b_fixed_pll = {
|
||||
static struct clk_regmap meson8b_fixed_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 0,
|
||||
|
@ -106,11 +71,6 @@ static struct clk_regmap meson8b_fixed_pll = {
|
|||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.frac = {
|
||||
.reg_off = HHI_MPLL_CNTL2,
|
||||
.shift = 0,
|
||||
|
@ -128,86 +88,134 @@ static struct clk_regmap meson8b_fixed_pll = {
|
|||
},
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fixed_pll",
|
||||
.name = "fixed_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap meson8b_fixed_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_MPLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fixed_pll",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll_dco" },
|
||||
.num_parents = 1,
|
||||
/*
|
||||
* This clock won't ever change at runtime so
|
||||
* CLK_SET_RATE_PARENT is not required
|
||||
*/
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap meson8b_vid_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_VID_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_VID_PLL_CNTL,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = HHI_VID_PLL_CNTL,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.l = {
|
||||
.reg_off = HHI_VID_PLL_CNTL,
|
||||
.shift = 31,
|
||||
.width = 1,
|
||||
},
|
||||
.rst = {
|
||||
.reg_off = HHI_VID_PLL_CNTL,
|
||||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap meson8b_vid_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_VID_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "vid_pll_dco" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap meson8b_sys_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = HHI_VID_PLL_CNTL,
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = HHI_VID_PLL_CNTL,
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_VID_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.l = {
|
||||
.reg_off = HHI_VID_PLL_CNTL,
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 31,
|
||||
.width = 1,
|
||||
},
|
||||
.rst = {
|
||||
.reg_off = HHI_VID_PLL_CNTL,
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = sys_pll_params_table,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll",
|
||||
.name = "sys_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap meson8b_sys_pll = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.m = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.l = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 31,
|
||||
.width = 1,
|
||||
},
|
||||
.rst = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = sys_pll_rate_table,
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = HHI_SYS_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sys_pll",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_names = (const char *[]){ "sys_pll_dco" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -879,6 +887,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
|
|||
[CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw,
|
||||
[CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw,
|
||||
[CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw,
|
||||
[CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw,
|
||||
[CLKID_PLL_VID_DCO] = &meson8b_vid_pll_dco.hw,
|
||||
[CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw,
|
||||
[CLK_NR_CLKS] = NULL,
|
||||
},
|
||||
.num = CLK_NR_CLKS,
|
||||
|
@ -987,6 +998,9 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
|
|||
&meson8b_nand_clk_sel,
|
||||
&meson8b_nand_clk_div,
|
||||
&meson8b_nand_clk_gate,
|
||||
&meson8b_fixed_pll_dco,
|
||||
&meson8b_vid_pll_dco,
|
||||
&meson8b_sys_pll_dco,
|
||||
};
|
||||
|
||||
static const struct meson8b_clk_reset_line {
|
||||
|
@ -1050,7 +1064,6 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
|
|||
container_of(rcdev, struct meson8b_clk_reset, reset);
|
||||
unsigned long flags;
|
||||
const struct meson8b_clk_reset_line *reset;
|
||||
u32 val;
|
||||
|
||||
if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
|
||||
return -EINVAL;
|
||||
|
@ -1059,12 +1072,12 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
|
|||
|
||||
spin_lock_irqsave(&meson_clk_lock, flags);
|
||||
|
||||
val = readl(meson8b_clk_reset->base + reset->reg);
|
||||
if (assert)
|
||||
val |= BIT(reset->bit_idx);
|
||||
regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
|
||||
BIT(reset->bit_idx), BIT(reset->bit_idx));
|
||||
else
|
||||
val &= ~BIT(reset->bit_idx);
|
||||
writel(val, meson8b_clk_reset->base + reset->reg);
|
||||
regmap_update_bits(meson8b_clk_reset->regmap, reset->reg,
|
||||
BIT(reset->bit_idx), 0);
|
||||
|
||||
spin_unlock_irqrestore(&meson_clk_lock, flags);
|
||||
|
||||
|
@ -1094,18 +1107,39 @@ static const struct regmap_config clkc_regmap_config = {
|
|||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
static int meson8b_clkc_probe(struct platform_device *pdev)
|
||||
static void __init meson8b_clkc_init(struct device_node *np)
|
||||
{
|
||||
int ret, i;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct meson8b_clk_reset *rstc;
|
||||
void __iomem *clk_base;
|
||||
struct regmap *map;
|
||||
int i, ret;
|
||||
|
||||
if (!clk_base)
|
||||
return -ENXIO;
|
||||
/* Generic clocks, PLLs and some of the reset-bits */
|
||||
clk_base = of_iomap(np, 1);
|
||||
if (!clk_base) {
|
||||
pr_err("%s: Unable to map clk base\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
map = devm_regmap_init_mmio(dev, clk_base, &clkc_regmap_config);
|
||||
map = regmap_init_mmio(NULL, clk_base, &clkc_regmap_config);
|
||||
if (IS_ERR(map))
|
||||
return PTR_ERR(map);
|
||||
return;
|
||||
|
||||
rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
|
||||
if (!rstc)
|
||||
return;
|
||||
|
||||
/* Reset Controller */
|
||||
rstc->regmap = map;
|
||||
rstc->reset.ops = &meson8b_clk_reset_ops;
|
||||
rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
|
||||
rstc->reset.of_node = np;
|
||||
ret = reset_controller_register(&rstc->reset);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to register clkc reset controller: %d\n",
|
||||
__func__, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Populate regmap for the regmap backed clocks */
|
||||
for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++)
|
||||
|
@ -1120,64 +1154,20 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
|
|||
if (!meson8b_hw_onecell_data.hws[i])
|
||||
continue;
|
||||
|
||||
ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[i]);
|
||||
ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
|
||||
&meson8b_hw_onecell_data);
|
||||
}
|
||||
|
||||
static const struct of_device_id meson8b_clkc_match_table[] = {
|
||||
{ .compatible = "amlogic,meson8-clkc" },
|
||||
{ .compatible = "amlogic,meson8b-clkc" },
|
||||
{ .compatible = "amlogic,meson8m2-clkc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver meson8b_driver = {
|
||||
.probe = meson8b_clkc_probe,
|
||||
.driver = {
|
||||
.name = "meson8b-clkc",
|
||||
.of_match_table = meson8b_clkc_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
builtin_platform_driver(meson8b_driver);
|
||||
|
||||
static void __init meson8b_clkc_reset_init(struct device_node *np)
|
||||
{
|
||||
struct meson8b_clk_reset *rstc;
|
||||
int ret;
|
||||
|
||||
/* Generic clocks, PLLs and some of the reset-bits */
|
||||
clk_base = of_iomap(np, 1);
|
||||
if (!clk_base) {
|
||||
pr_err("%s: Unable to map clk base\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
|
||||
if (!rstc)
|
||||
return;
|
||||
|
||||
/* Reset Controller */
|
||||
rstc->base = clk_base;
|
||||
rstc->reset.ops = &meson8b_clk_reset_ops;
|
||||
rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
|
||||
rstc->reset.of_node = np;
|
||||
ret = reset_controller_register(&rstc->reset);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to register clkc reset controller: %d\n",
|
||||
__func__, ret);
|
||||
return;
|
||||
}
|
||||
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
|
||||
&meson8b_hw_onecell_data);
|
||||
if (ret)
|
||||
pr_err("%s: failed to register clock provider\n", __func__);
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
|
||||
meson8b_clkc_reset_init);
|
||||
meson8b_clkc_init);
|
||||
CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
|
||||
meson8b_clkc_reset_init);
|
||||
meson8b_clkc_init);
|
||||
CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
|
||||
meson8b_clkc_reset_init);
|
||||
meson8b_clkc_init);
|
||||
|
|
|
@ -75,8 +75,11 @@
|
|||
#define CLKID_FCLK_DIV7_DIV 109
|
||||
#define CLKID_NAND_SEL 110
|
||||
#define CLKID_NAND_DIV 111
|
||||
#define CLKID_PLL_FIXED_DCO 113
|
||||
#define CLKID_PLL_VID_DCO 114
|
||||
#define CLKID_PLL_SYS_DCO 115
|
||||
|
||||
#define CLK_NR_CLKS 113
|
||||
#define CLK_NR_CLKS 116
|
||||
|
||||
/*
|
||||
* include the CLKID and RESETID that have
|
||||
|
|
|
@ -153,7 +153,6 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
|
|||
goto fail4;
|
||||
}
|
||||
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
|
||||
ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
|
||||
if (ret)
|
||||
goto fail_clk_add;
|
||||
|
|
|
@ -56,6 +56,15 @@
|
|||
struct clk_periph_driver_data {
|
||||
struct clk_hw_onecell_data *hw_data;
|
||||
spinlock_t lock;
|
||||
void __iomem *reg;
|
||||
|
||||
/* Storage registers for suspend/resume operations */
|
||||
u32 tbg_sel;
|
||||
u32 div_sel0;
|
||||
u32 div_sel1;
|
||||
u32 div_sel2;
|
||||
u32 clk_sel;
|
||||
u32 clk_dis;
|
||||
};
|
||||
|
||||
struct clk_double_div {
|
||||
|
@ -672,6 +681,40 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
|
|||
return PTR_ERR_OR_ZERO(*hw);
|
||||
}
|
||||
|
||||
static int __maybe_unused armada_3700_periph_clock_suspend(struct device *dev)
|
||||
{
|
||||
struct clk_periph_driver_data *data = dev_get_drvdata(dev);
|
||||
|
||||
data->tbg_sel = readl(data->reg + TBG_SEL);
|
||||
data->div_sel0 = readl(data->reg + DIV_SEL0);
|
||||
data->div_sel1 = readl(data->reg + DIV_SEL1);
|
||||
data->div_sel2 = readl(data->reg + DIV_SEL2);
|
||||
data->clk_sel = readl(data->reg + CLK_SEL);
|
||||
data->clk_dis = readl(data->reg + CLK_DIS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused armada_3700_periph_clock_resume(struct device *dev)
|
||||
{
|
||||
struct clk_periph_driver_data *data = dev_get_drvdata(dev);
|
||||
|
||||
/* Follow the same order than what the Cortex-M3 does (ATF code) */
|
||||
writel(data->clk_dis, data->reg + CLK_DIS);
|
||||
writel(data->div_sel0, data->reg + DIV_SEL0);
|
||||
writel(data->div_sel1, data->reg + DIV_SEL1);
|
||||
writel(data->div_sel2, data->reg + DIV_SEL2);
|
||||
writel(data->tbg_sel, data->reg + TBG_SEL);
|
||||
writel(data->clk_sel, data->reg + CLK_SEL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend,
|
||||
armada_3700_periph_clock_resume)
|
||||
};
|
||||
|
||||
static int armada_3700_periph_clock_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_periph_driver_data *driver_data;
|
||||
|
@ -680,7 +723,6 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
int num_periph = 0, i, ret;
|
||||
struct resource *res;
|
||||
void __iomem *reg;
|
||||
|
||||
data = of_device_get_match_data(dev);
|
||||
if (!data)
|
||||
|
@ -689,11 +731,6 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev)
|
|||
while (data[num_periph].name)
|
||||
num_periph++;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
|
||||
if (!driver_data)
|
||||
return -ENOMEM;
|
||||
|
@ -706,12 +743,16 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
driver_data->hw_data->num = num_periph;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
driver_data->reg = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(driver_data->reg))
|
||||
return PTR_ERR(driver_data->reg);
|
||||
|
||||
spin_lock_init(&driver_data->lock);
|
||||
|
||||
for (i = 0; i < num_periph; i++) {
|
||||
struct clk_hw **hw = &driver_data->hw_data->hws[i];
|
||||
|
||||
if (armada_3700_add_composite_clk(&data[i], reg,
|
||||
if (armada_3700_add_composite_clk(&data[i], driver_data->reg,
|
||||
&driver_data->lock, dev, hw))
|
||||
dev_err(dev, "Can't register periph clock %s\n",
|
||||
data[i].name);
|
||||
|
@ -749,6 +790,7 @@ static struct platform_driver armada_3700_periph_clock_driver = {
|
|||
.driver = {
|
||||
.name = "marvell-armada-3700-periph-clock",
|
||||
.of_match_table = armada_3700_periph_clock_of_match,
|
||||
.pm = &armada_3700_periph_clock_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -64,17 +64,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
|
|||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
|
||||
"osc24M", 0x010,
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0",
|
||||
"osc24M", 0x010,
|
||||
192000000, /* Minimum rate */
|
||||
1008000000, /* Maximum rate */
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
|
||||
"osc24M", 0x018,
|
||||
|
@ -125,17 +127,19 @@ static struct ccu_nk pll_periph1_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1",
|
||||
"osc24M", 0x030,
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1",
|
||||
"osc24M", 0x030,
|
||||
192000000, /* Minimum rate */
|
||||
1008000000, /* Maximum rate */
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
|
||||
"osc24M", 0x038,
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
#define CLK_PLL_AUDIO_2X 4
|
||||
#define CLK_PLL_AUDIO_4X 5
|
||||
#define CLK_PLL_AUDIO_8X 6
|
||||
#define CLK_PLL_VIDEO0 7
|
||||
|
||||
/* PLL_VIDEO0 exported for HDMI PHY */
|
||||
|
||||
#define CLK_PLL_VIDEO0_2X 8
|
||||
#define CLK_PLL_VE 9
|
||||
#define CLK_PLL_DDR0 10
|
||||
|
|
|
@ -224,7 +224,7 @@ static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2",
|
|||
psi_ahb1_ahb2_parents,
|
||||
0x510,
|
||||
0, 5, /* M */
|
||||
16, 2, /* P */
|
||||
8, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
0);
|
||||
|
||||
|
@ -233,19 +233,19 @@ static const char * const ahb3_apb1_apb2_parents[] = { "osc24M", "osc32k",
|
|||
"pll-periph0" };
|
||||
static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c,
|
||||
0, 5, /* M */
|
||||
16, 2, /* P */
|
||||
8, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520,
|
||||
0, 5, /* M */
|
||||
16, 2, /* P */
|
||||
8, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524,
|
||||
0, 5, /* M */
|
||||
16, 2, /* P */
|
||||
8, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
0);
|
||||
|
||||
|
@ -352,7 +352,7 @@ static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2",
|
|||
static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2",
|
||||
0x79c, BIT(0), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x79c, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0);
|
||||
|
||||
|
@ -408,26 +408,29 @@ static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0);
|
|||
|
||||
static const char * const mmc_parents[] = { "osc24M", "pll-periph0-2x",
|
||||
"pll-periph1-2x" };
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc_parents, 0x830,
|
||||
0, 4, /* M */
|
||||
8, 2, /* N */
|
||||
24, 3, /* mux */
|
||||
BIT(31),/* gate */
|
||||
0);
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830,
|
||||
0, 4, /* M */
|
||||
8, 2, /* N */
|
||||
24, 3, /* mux */
|
||||
BIT(31), /* gate */
|
||||
2, /* post-div */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc_parents, 0x834,
|
||||
0, 4, /* M */
|
||||
8, 2, /* N */
|
||||
24, 3, /* mux */
|
||||
BIT(31),/* gate */
|
||||
0);
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834,
|
||||
0, 4, /* M */
|
||||
8, 2, /* N */
|
||||
24, 3, /* mux */
|
||||
BIT(31), /* gate */
|
||||
2, /* post-div */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc_parents, 0x838,
|
||||
0, 4, /* M */
|
||||
8, 2, /* N */
|
||||
24, 3, /* mux */
|
||||
BIT(31),/* gate */
|
||||
0);
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838,
|
||||
0, 4, /* M */
|
||||
8, 2, /* N */
|
||||
24, 3, /* mux */
|
||||
BIT(31), /* gate */
|
||||
2, /* post-div */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0);
|
||||
|
|
|
@ -108,6 +108,7 @@ static struct ccu_nkmp pll_video0_clk = {
|
|||
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
|
||||
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
|
||||
.p = _SUNXI_CCU_DIV(0, 2), /* output divider */
|
||||
.max_rate = 3000000000UL,
|
||||
.common = {
|
||||
.reg = 0x010,
|
||||
.lock_reg = CCU_SUN8I_A83T_LOCK_REG,
|
||||
|
@ -220,6 +221,7 @@ static struct ccu_nkmp pll_video1_clk = {
|
|||
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
|
||||
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
|
||||
.p = _SUNXI_CCU_DIV(0, 2), /* external divider p */
|
||||
.max_rate = 3000000000UL,
|
||||
.common = {
|
||||
.reg = 0x04c,
|
||||
.lock_reg = CCU_SUN8I_A83T_LOCK_REG,
|
||||
|
|
|
@ -69,18 +69,19 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
|
|||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video_clk, "pll-video",
|
||||
"osc24M", 0x0010,
|
||||
192000000, /* Minimum rate */
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video_clk, "pll-video",
|
||||
"osc24M", 0x0010,
|
||||
192000000, /* Minimum rate */
|
||||
912000000, /* Maximum rate */
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
|
||||
"osc24M", 0x0018,
|
||||
|
|
|
@ -65,19 +65,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
|
|||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
/* TODO: The result of N/M is required to be in [8, 25] range. */
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0",
|
||||
"osc24M", 0x0010,
|
||||
192000000, /* Minimum rate */
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0",
|
||||
"osc24M", 0x0010,
|
||||
192000000, /* Minimum rate */
|
||||
1008000000, /* Maximum rate */
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
/* TODO: The result of N/M is required to be in [8, 25] range. */
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
|
||||
|
@ -152,19 +152,19 @@ static struct ccu_nk pll_periph1_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
/* TODO: The result of N/M is required to be in [8, 25] range. */
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1",
|
||||
"osc24M", 0x030,
|
||||
192000000, /* Minimum rate */
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1",
|
||||
"osc24M", 0x030,
|
||||
192000000, /* Minimum rate */
|
||||
1008000000, /* Maximum rate */
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static struct ccu_nkm pll_sata_clk = {
|
||||
.enable = BIT(31),
|
||||
|
|
|
@ -137,6 +137,13 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate *= nkmp->fixed_post_div;
|
||||
|
||||
if (nkmp->max_rate && rate > nkmp->max_rate) {
|
||||
rate = nkmp->max_rate;
|
||||
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate /= nkmp->fixed_post_div;
|
||||
return rate;
|
||||
}
|
||||
|
||||
_nkmp.min_n = nkmp->n.min ?: 1;
|
||||
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
|
||||
_nkmp.min_k = nkmp->k.min ?: 1;
|
||||
|
|
|
@ -35,6 +35,7 @@ struct ccu_nkmp {
|
|||
struct ccu_div_internal p;
|
||||
|
||||
unsigned int fixed_post_div;
|
||||
unsigned int max_rate;
|
||||
|
||||
struct ccu_common common;
|
||||
};
|
||||
|
|
|
@ -124,6 +124,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
return rate;
|
||||
}
|
||||
|
||||
if (nm->max_rate && rate > nm->max_rate) {
|
||||
rate = nm->max_rate;
|
||||
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate /= nm->fixed_post_div;
|
||||
return rate;
|
||||
}
|
||||
|
||||
if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) {
|
||||
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate /= nm->fixed_post_div;
|
||||
|
|
|
@ -38,6 +38,7 @@ struct ccu_nm {
|
|||
|
||||
unsigned int fixed_post_div;
|
||||
unsigned int min_rate;
|
||||
unsigned int max_rate;
|
||||
|
||||
struct ccu_common common;
|
||||
};
|
||||
|
@ -115,6 +116,35 @@ struct ccu_nm {
|
|||
}, \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \
|
||||
_parent, _reg, \
|
||||
_min_rate, _max_rate, \
|
||||
_nshift, _nwidth, \
|
||||
_mshift, _mwidth, \
|
||||
_frac_en, _frac_sel, \
|
||||
_frac_rate_0, \
|
||||
_frac_rate_1, \
|
||||
_gate, _lock, _flags) \
|
||||
struct ccu_nm _struct = { \
|
||||
.enable = _gate, \
|
||||
.lock = _lock, \
|
||||
.n = _SUNXI_CCU_MULT(_nshift, _nwidth), \
|
||||
.m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
|
||||
.frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \
|
||||
_frac_rate_0, \
|
||||
_frac_rate_1), \
|
||||
.min_rate = _min_rate, \
|
||||
.max_rate = _max_rate, \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.features = CCU_FEATURE_FRACTIONAL, \
|
||||
.hw.init = CLK_HW_INIT(_name, \
|
||||
_parent, \
|
||||
&ccu_nm_ops, \
|
||||
_flags), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
|
||||
_nshift, _nwidth, \
|
||||
_mshift, _mwidth, \
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_
|
||||
#define _DT_BINDINGS_CLK_SUN50I_A64_H_
|
||||
|
||||
#define CLK_PLL_VIDEO0 7
|
||||
#define CLK_PLL_PERIPH0 11
|
||||
|
||||
#define CLK_BUS_MIPI_DSI 28
|
||||
|
|
Loading…
Reference in New Issue
Block a user