Merge branches 'clk-mvebu', 'clk-phase', 'clk-nxp', 'clk-mtk2712' and 'clk-qcom-rpmcc' into clk-next
* clk-mvebu: clk: mvebu: armada-38x: add support for missing clocks clk: mvebu: cp110: Fix clock tree representation * clk-phase: clk: Don't show the incorrect clock phase clk: update cached phase to respect the fact when setting phase * clk-nxp: clk: lpc32xx: Set name of regmap_config * clk-mtk2712: clk: mediatek: update clock driver of MT2712 dt-bindings: clock: add clocks for MT2712 * clk-qcom-rpmcc: clk: qcom: rpmcc: Add support to XO buffered clocks
This commit is contained in:
commit
fbc20b8c3c
|
@ -2311,8 +2311,11 @@ static int clk_core_set_phase_nolock(struct clk_core *core, int degrees)
|
|||
|
||||
trace_clk_set_phase(core, degrees);
|
||||
|
||||
if (core->ops->set_phase)
|
||||
if (core->ops->set_phase) {
|
||||
ret = core->ops->set_phase(core->hw, degrees);
|
||||
if (!ret)
|
||||
core->phase = degrees;
|
||||
}
|
||||
|
||||
trace_clk_set_phase_complete(core, degrees);
|
||||
|
||||
|
@ -2372,6 +2375,9 @@ static int clk_core_get_phase(struct clk_core *core)
|
|||
int ret;
|
||||
|
||||
clk_prepare_lock();
|
||||
/* Always try to update cached phase if possible */
|
||||
if (core->ops->get_phase)
|
||||
core->phase = core->ops->get_phase(core->hw);
|
||||
ret = core->phase;
|
||||
clk_prepare_unlock();
|
||||
|
||||
|
|
|
@ -221,6 +221,8 @@ static const struct mtk_fixed_factor top_divs[] = {
|
|||
4),
|
||||
FACTOR(CLK_TOP_D2A_ULCLK_6P5M, "d2a_ulclk_6p5m", "clk26m", 1,
|
||||
4),
|
||||
FACTOR(CLK_TOP_APLL1_D3, "apll1_d3", "apll1_ck", 1,
|
||||
3),
|
||||
};
|
||||
|
||||
static const char * const axi_parents[] = {
|
||||
|
@ -625,7 +627,7 @@ static const char * const ether_125m_parents[] = {
|
|||
static const char * const ether_50m_parents[] = {
|
||||
"clk26m",
|
||||
"etherpll_50m",
|
||||
"univpll_d26",
|
||||
"apll1_d3",
|
||||
"univpll3_d4"
|
||||
};
|
||||
|
||||
|
@ -686,7 +688,7 @@ static const char * const i2c_parents[] = {
|
|||
|
||||
static const char * const msdc0p_aes_parents[] = {
|
||||
"clk26m",
|
||||
"msdcpll_ck",
|
||||
"syspll_d2",
|
||||
"univpll_d3",
|
||||
"vcodecpll_ck"
|
||||
};
|
||||
|
@ -719,6 +721,17 @@ static const char * const aud_apll2_parents[] = {
|
|||
"clkaud_ext_i_2"
|
||||
};
|
||||
|
||||
static const char * const apll1_ref_parents[] = {
|
||||
"clkaud_ext_i_2",
|
||||
"clkaud_ext_i_1",
|
||||
"clki2si0_mck_i",
|
||||
"clki2si1_mck_i",
|
||||
"clki2si2_mck_i",
|
||||
"clktdmin_mclk_i",
|
||||
"clki2si2_mck_i",
|
||||
"clktdmin_mclk_i"
|
||||
};
|
||||
|
||||
static const char * const audull_vtx_parents[] = {
|
||||
"d2a_ulclk_6p5m",
|
||||
"clkaud_ext_i_0"
|
||||
|
@ -886,6 +899,10 @@ static struct mtk_composite top_muxes[] = {
|
|||
aud_apll2_parents, 0x134, 1, 1),
|
||||
MUX(CLK_TOP_DA_AUDULL_VTX_6P5M_SEL, "audull_vtx_sel",
|
||||
audull_vtx_parents, 0x134, 31, 1),
|
||||
MUX(CLK_TOP_APLL1_REF_SEL, "apll1_ref_sel",
|
||||
apll1_ref_parents, 0x134, 4, 3),
|
||||
MUX(CLK_TOP_APLL2_REF_SEL, "apll2_ref_sel",
|
||||
apll1_ref_parents, 0x134, 7, 3),
|
||||
};
|
||||
|
||||
static const char * const mcu_mp0_parents[] = {
|
||||
|
@ -932,36 +949,56 @@ static const struct mtk_clk_divider top_adj_divs[] = {
|
|||
DIV_ADJ(CLK_TOP_APLL_DIV7, "apll_div7", "i2si3_sel", 0x128, 24, 8),
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs top_cg_regs = {
|
||||
static const struct mtk_gate_regs top0_cg_regs = {
|
||||
.set_ofs = 0x120,
|
||||
.clr_ofs = 0x120,
|
||||
.sta_ofs = 0x120,
|
||||
};
|
||||
|
||||
#define GATE_TOP(_id, _name, _parent, _shift) { \
|
||||
static const struct mtk_gate_regs top1_cg_regs = {
|
||||
.set_ofs = 0x424,
|
||||
.clr_ofs = 0x424,
|
||||
.sta_ofs = 0x424,
|
||||
};
|
||||
|
||||
#define GATE_TOP0(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &top_cg_regs, \
|
||||
.regs = &top0_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_no_setclr, \
|
||||
}
|
||||
|
||||
#define GATE_TOP1(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &top1_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate top_clks[] = {
|
||||
GATE_TOP(CLK_TOP_APLL_DIV_PDN0, "apll_div_pdn0", "i2so1_sel", 0),
|
||||
GATE_TOP(CLK_TOP_APLL_DIV_PDN1, "apll_div_pdn1", "i2so2_sel", 1),
|
||||
GATE_TOP(CLK_TOP_APLL_DIV_PDN2, "apll_div_pdn2", "i2so3_sel", 2),
|
||||
GATE_TOP(CLK_TOP_APLL_DIV_PDN3, "apll_div_pdn3", "tdmo0_sel", 3),
|
||||
GATE_TOP(CLK_TOP_APLL_DIV_PDN4, "apll_div_pdn4", "tdmo1_sel", 4),
|
||||
GATE_TOP(CLK_TOP_APLL_DIV_PDN5, "apll_div_pdn5", "i2si1_sel", 5),
|
||||
GATE_TOP(CLK_TOP_APLL_DIV_PDN6, "apll_div_pdn6", "i2si2_sel", 6),
|
||||
GATE_TOP(CLK_TOP_APLL_DIV_PDN7, "apll_div_pdn7", "i2si3_sel", 7),
|
||||
/* TOP0 */
|
||||
GATE_TOP0(CLK_TOP_APLL_DIV_PDN0, "apll_div_pdn0", "i2so1_sel", 0),
|
||||
GATE_TOP0(CLK_TOP_APLL_DIV_PDN1, "apll_div_pdn1", "i2so2_sel", 1),
|
||||
GATE_TOP0(CLK_TOP_APLL_DIV_PDN2, "apll_div_pdn2", "i2so3_sel", 2),
|
||||
GATE_TOP0(CLK_TOP_APLL_DIV_PDN3, "apll_div_pdn3", "tdmo0_sel", 3),
|
||||
GATE_TOP0(CLK_TOP_APLL_DIV_PDN4, "apll_div_pdn4", "tdmo1_sel", 4),
|
||||
GATE_TOP0(CLK_TOP_APLL_DIV_PDN5, "apll_div_pdn5", "i2si1_sel", 5),
|
||||
GATE_TOP0(CLK_TOP_APLL_DIV_PDN6, "apll_div_pdn6", "i2si2_sel", 6),
|
||||
GATE_TOP0(CLK_TOP_APLL_DIV_PDN7, "apll_div_pdn7", "i2si3_sel", 7),
|
||||
/* TOP1 */
|
||||
GATE_TOP1(CLK_TOP_NFI2X_EN, "nfi2x_en", "nfi2x_sel", 0),
|
||||
GATE_TOP1(CLK_TOP_NFIECC_EN, "nfiecc_en", "nfiecc_sel", 1),
|
||||
GATE_TOP1(CLK_TOP_NFI1X_CK_EN, "nfi1x_ck_en", "nfi2x_sel", 2),
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs infra_cg_regs = {
|
||||
.set_ofs = 0x40,
|
||||
.clr_ofs = 0x44,
|
||||
.sta_ofs = 0x40,
|
||||
.sta_ofs = 0x48,
|
||||
};
|
||||
|
||||
#define GATE_INFRA(_id, _name, _parent, _shift) { \
|
||||
|
@ -1120,6 +1157,10 @@ static const struct mtk_gate peri_clks[] = {
|
|||
"msdc50_0_h_sel", 4),
|
||||
GATE_PERI2(CLK_PERI_MSDC50_3_HCLK_EN, "per_msdc50_3_h",
|
||||
"msdc50_3_h_sel", 5),
|
||||
GATE_PERI2(CLK_PERI_MSDC30_0_QTR_EN, "per_msdc30_0_q",
|
||||
"axi_sel", 6),
|
||||
GATE_PERI2(CLK_PERI_MSDC30_3_QTR_EN, "per_msdc30_3_q",
|
||||
"mem_sel", 7),
|
||||
};
|
||||
|
||||
#define MT2712_PLL_FMAX (3000UL * MHZ)
|
||||
|
|
|
@ -46,11 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem *sar)
|
|||
}
|
||||
|
||||
static const u32 armada_38x_cpu_frequencies[] __initconst = {
|
||||
0, 0, 0, 0,
|
||||
1066 * 1000 * 1000, 0, 0, 0,
|
||||
666 * 1000 * 1000, 0, 800 * 1000 * 1000, 0,
|
||||
1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
|
||||
1332 * 1000 * 1000, 0, 0, 0,
|
||||
1600 * 1000 * 1000, 0, 0, 0,
|
||||
1866 * 1000 * 1000,
|
||||
1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000,
|
||||
};
|
||||
|
||||
static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
|
||||
|
@ -76,11 +76,11 @@ static const struct coreclk_ratio armada_38x_coreclk_ratios[] __initconst = {
|
|||
};
|
||||
|
||||
static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
|
||||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
{1, 2}, {0, 1}, {0, 1}, {0, 1},
|
||||
{1, 2}, {0, 1}, {0, 1}, {0, 1},
|
||||
{1, 2}, {0, 1}, {1, 2}, {0, 1},
|
||||
{1, 2}, {0, 1}, {1, 2}, {0, 1},
|
||||
{1, 2}, {0, 1}, {0, 1}, {0, 1},
|
||||
{1, 2}, {0, 1}, {0, 1}, {0, 1},
|
||||
{1, 2}, {0, 1}, {0, 1}, {1, 2},
|
||||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
|
@ -91,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst = {
|
|||
{1, 2}, {0, 1}, {0, 1}, {0, 1},
|
||||
{1, 2}, {0, 1}, {0, 1}, {0, 1},
|
||||
{1, 2}, {0, 1}, {0, 1}, {0, 1},
|
||||
{1, 2}, {0, 1}, {0, 1}, {0, 1},
|
||||
{1, 2}, {0, 1}, {0, 1}, {7, 15},
|
||||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
|
|
|
@ -13,18 +13,17 @@
|
|||
/*
|
||||
* CP110 has 6 core clocks:
|
||||
*
|
||||
* - APLL (1 Ghz)
|
||||
* - PPv2 core (1/3 APLL)
|
||||
* - EIP (1/2 APLL)
|
||||
* - Core (1/2 EIP)
|
||||
* - SDIO (2/5 APLL)
|
||||
* - PLL0 (1 Ghz)
|
||||
* - PPv2 core (1/3 PLL0)
|
||||
* - x2 Core (1/2 PLL0)
|
||||
* - Core (1/2 x2 Core)
|
||||
* - SDIO (2/5 PLL0)
|
||||
*
|
||||
* - NAND clock, which is either:
|
||||
* - Equal to SDIO clock
|
||||
* - 2/5 APLL
|
||||
* - 2/5 PLL0
|
||||
*
|
||||
* CP110 has 32 gatable clocks, for the various peripherals in the
|
||||
* IP. They have fairly complicated parent/child relationships.
|
||||
* CP110 has 32 gatable clocks, for the various peripherals in the IP.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "cp110-system-controller: " fmt
|
||||
|
@ -53,9 +52,9 @@ enum {
|
|||
#define CP110_CLK_NUM \
|
||||
(CP110_MAX_CORE_CLOCKS + CP110_MAX_GATABLE_CLOCKS)
|
||||
|
||||
#define CP110_CORE_APLL 0
|
||||
#define CP110_CORE_PLL0 0
|
||||
#define CP110_CORE_PPV2 1
|
||||
#define CP110_CORE_EIP 2
|
||||
#define CP110_CORE_X2CORE 2
|
||||
#define CP110_CORE_CORE 3
|
||||
#define CP110_CORE_NAND 4
|
||||
#define CP110_CORE_SDIO 5
|
||||
|
@ -237,7 +236,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
|
|||
struct regmap *regmap;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name,
|
||||
const char *ppv2_name, *pll0_name, *core_name, *x2core_name, *nand_name,
|
||||
*sdio_name;
|
||||
struct clk_hw_onecell_data *cp110_clk_data;
|
||||
struct clk_hw *hw, **cp110_clks;
|
||||
|
@ -263,20 +262,20 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
|
|||
cp110_clks = cp110_clk_data->hws;
|
||||
cp110_clk_data->num = CP110_CLK_NUM;
|
||||
|
||||
/* Register the APLL which is the root of the hw tree */
|
||||
apll_name = cp110_unique_name(dev, syscon_node, "apll");
|
||||
hw = clk_hw_register_fixed_rate(NULL, apll_name, NULL, 0,
|
||||
/* Register the PLL0 which is the root of the hw tree */
|
||||
pll0_name = cp110_unique_name(dev, syscon_node, "pll0");
|
||||
hw = clk_hw_register_fixed_rate(NULL, pll0_name, NULL, 0,
|
||||
1000 * 1000 * 1000);
|
||||
if (IS_ERR(hw)) {
|
||||
ret = PTR_ERR(hw);
|
||||
goto fail_apll;
|
||||
goto fail_pll0;
|
||||
}
|
||||
|
||||
cp110_clks[CP110_CORE_APLL] = hw;
|
||||
cp110_clks[CP110_CORE_PLL0] = hw;
|
||||
|
||||
/* PPv2 is APLL/3 */
|
||||
/* PPv2 is PLL0/3 */
|
||||
ppv2_name = cp110_unique_name(dev, syscon_node, "ppv2-core");
|
||||
hw = clk_hw_register_fixed_factor(NULL, ppv2_name, apll_name, 0, 1, 3);
|
||||
hw = clk_hw_register_fixed_factor(NULL, ppv2_name, pll0_name, 0, 1, 3);
|
||||
if (IS_ERR(hw)) {
|
||||
ret = PTR_ERR(hw);
|
||||
goto fail_ppv2;
|
||||
|
@ -284,30 +283,32 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
|
|||
|
||||
cp110_clks[CP110_CORE_PPV2] = hw;
|
||||
|
||||
/* EIP clock is APLL/2 */
|
||||
eip_name = cp110_unique_name(dev, syscon_node, "eip");
|
||||
hw = clk_hw_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2);
|
||||
/* X2CORE clock is PLL0/2 */
|
||||
x2core_name = cp110_unique_name(dev, syscon_node, "x2core");
|
||||
hw = clk_hw_register_fixed_factor(NULL, x2core_name, pll0_name,
|
||||
0, 1, 2);
|
||||
if (IS_ERR(hw)) {
|
||||
ret = PTR_ERR(hw);
|
||||
goto fail_eip;
|
||||
}
|
||||
|
||||
cp110_clks[CP110_CORE_EIP] = hw;
|
||||
cp110_clks[CP110_CORE_X2CORE] = hw;
|
||||
|
||||
/* Core clock is EIP/2 */
|
||||
/* Core clock is X2CORE/2 */
|
||||
core_name = cp110_unique_name(dev, syscon_node, "core");
|
||||
hw = clk_hw_register_fixed_factor(NULL, core_name, eip_name, 0, 1, 2);
|
||||
hw = clk_hw_register_fixed_factor(NULL, core_name, x2core_name,
|
||||
0, 1, 2);
|
||||
if (IS_ERR(hw)) {
|
||||
ret = PTR_ERR(hw);
|
||||
goto fail_core;
|
||||
}
|
||||
|
||||
cp110_clks[CP110_CORE_CORE] = hw;
|
||||
/* NAND can be either APLL/2.5 or core clock */
|
||||
/* NAND can be either PLL0/2.5 or core clock */
|
||||
nand_name = cp110_unique_name(dev, syscon_node, "nand-core");
|
||||
if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK)
|
||||
hw = clk_hw_register_fixed_factor(NULL, nand_name,
|
||||
apll_name, 0, 2, 5);
|
||||
pll0_name, 0, 2, 5);
|
||||
else
|
||||
hw = clk_hw_register_fixed_factor(NULL, nand_name,
|
||||
core_name, 0, 1, 1);
|
||||
|
@ -318,10 +319,10 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
|
|||
|
||||
cp110_clks[CP110_CORE_NAND] = hw;
|
||||
|
||||
/* SDIO clock is APLL/2.5 */
|
||||
/* SDIO clock is PLL0/2.5 */
|
||||
sdio_name = cp110_unique_name(dev, syscon_node, "sdio-core");
|
||||
hw = clk_hw_register_fixed_factor(NULL, sdio_name,
|
||||
apll_name, 0, 2, 5);
|
||||
pll0_name, 0, 2, 5);
|
||||
if (IS_ERR(hw)) {
|
||||
ret = PTR_ERR(hw);
|
||||
goto fail_sdio;
|
||||
|
@ -341,40 +342,23 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
|
|||
continue;
|
||||
|
||||
switch (i) {
|
||||
case CP110_GATE_AUDIO:
|
||||
case CP110_GATE_COMM_UNIT:
|
||||
case CP110_GATE_EIP150:
|
||||
case CP110_GATE_EIP197:
|
||||
case CP110_GATE_SLOW_IO:
|
||||
parent = gate_name[CP110_GATE_MAIN];
|
||||
break;
|
||||
case CP110_GATE_MG:
|
||||
parent = gate_name[CP110_GATE_MG_CORE];
|
||||
break;
|
||||
case CP110_GATE_NAND:
|
||||
parent = nand_name;
|
||||
break;
|
||||
case CP110_GATE_MG:
|
||||
case CP110_GATE_GOP_DP:
|
||||
case CP110_GATE_PPV2:
|
||||
parent = ppv2_name;
|
||||
break;
|
||||
case CP110_GATE_SDIO:
|
||||
parent = sdio_name;
|
||||
break;
|
||||
case CP110_GATE_GOP_DP:
|
||||
parent = gate_name[CP110_GATE_SDMMC_GOP];
|
||||
break;
|
||||
case CP110_GATE_XOR1:
|
||||
case CP110_GATE_XOR0:
|
||||
case CP110_GATE_PCIE_X1_0:
|
||||
case CP110_GATE_PCIE_X1_1:
|
||||
case CP110_GATE_MAIN:
|
||||
case CP110_GATE_PCIE_XOR:
|
||||
case CP110_GATE_PCIE_X4:
|
||||
parent = gate_name[CP110_GATE_PCIE_XOR];
|
||||
break;
|
||||
case CP110_GATE_SATA:
|
||||
case CP110_GATE_USB3H0:
|
||||
case CP110_GATE_USB3H1:
|
||||
case CP110_GATE_USB3DEV:
|
||||
parent = gate_name[CP110_GATE_SATA_USB];
|
||||
case CP110_GATE_EIP150:
|
||||
case CP110_GATE_EIP197:
|
||||
parent = x2core_name;
|
||||
break;
|
||||
default:
|
||||
parent = core_name;
|
||||
|
@ -413,12 +397,12 @@ fail_sdio:
|
|||
fail_nand:
|
||||
clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]);
|
||||
fail_core:
|
||||
clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]);
|
||||
clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_X2CORE]);
|
||||
fail_eip:
|
||||
clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]);
|
||||
fail_ppv2:
|
||||
clk_hw_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]);
|
||||
fail_apll:
|
||||
clk_hw_unregister_fixed_rate(cp110_clks[CP110_CORE_PLL0]);
|
||||
fail_pll0:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#define LPC32XX_USB_CLK_STS 0xF8
|
||||
|
||||
static struct regmap_config lpc32xx_scb_regmap_config = {
|
||||
.name = "scb",
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#define QCOM_RPM_MISC_CLK_TYPE 0x306b6c63
|
||||
#define QCOM_RPM_SCALING_ENABLE_ID 0x2
|
||||
#define QCOM_RPM_XO_MODE_ON 0x2
|
||||
|
||||
#define DEFINE_CLK_RPM(_platform, _name, _active, r_id) \
|
||||
static struct clk_rpm _platform##_##_active; \
|
||||
|
@ -56,6 +57,18 @@
|
|||
}, \
|
||||
}
|
||||
|
||||
#define DEFINE_CLK_RPM_XO_BUFFER(_platform, _name, _active, offset) \
|
||||
static struct clk_rpm _platform##_##_name = { \
|
||||
.rpm_clk_id = QCOM_RPM_CXO_BUFFERS, \
|
||||
.xo_offset = (offset), \
|
||||
.hw.init = &(struct clk_init_data){ \
|
||||
.ops = &clk_rpm_xo_ops, \
|
||||
.name = #_name, \
|
||||
.parent_names = (const char *[]){ "cxo_board" }, \
|
||||
.num_parents = 1, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define DEFINE_CLK_RPM_FIXED(_platform, _name, _active, r_id, r) \
|
||||
static struct clk_rpm _platform##_##_name = { \
|
||||
.rpm_clk_id = (r_id), \
|
||||
|
@ -126,8 +139,11 @@
|
|||
|
||||
#define to_clk_rpm(_hw) container_of(_hw, struct clk_rpm, hw)
|
||||
|
||||
struct rpm_cc;
|
||||
|
||||
struct clk_rpm {
|
||||
const int rpm_clk_id;
|
||||
const int xo_offset;
|
||||
const bool active_only;
|
||||
unsigned long rate;
|
||||
bool enabled;
|
||||
|
@ -135,12 +151,15 @@ struct clk_rpm {
|
|||
struct clk_rpm *peer;
|
||||
struct clk_hw hw;
|
||||
struct qcom_rpm *rpm;
|
||||
struct rpm_cc *rpm_cc;
|
||||
};
|
||||
|
||||
struct rpm_cc {
|
||||
struct qcom_rpm *rpm;
|
||||
struct clk_rpm **clks;
|
||||
size_t num_clks;
|
||||
u32 xo_buffer_value;
|
||||
struct mutex xo_lock;
|
||||
};
|
||||
|
||||
struct rpm_clk_desc {
|
||||
|
@ -159,7 +178,8 @@ static int clk_rpm_handoff(struct clk_rpm *r)
|
|||
* The vendor tree simply reads the status for this
|
||||
* RPM clock.
|
||||
*/
|
||||
if (r->rpm_clk_id == QCOM_RPM_PLL_4)
|
||||
if (r->rpm_clk_id == QCOM_RPM_PLL_4 ||
|
||||
r->rpm_clk_id == QCOM_RPM_CXO_BUFFERS)
|
||||
return 0;
|
||||
|
||||
ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
|
||||
|
@ -288,6 +308,46 @@ out:
|
|||
mutex_unlock(&rpm_clk_lock);
|
||||
}
|
||||
|
||||
static int clk_rpm_xo_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_rpm *r = to_clk_rpm(hw);
|
||||
struct rpm_cc *rcc = r->rpm_cc;
|
||||
int ret, clk_id = r->rpm_clk_id;
|
||||
u32 value;
|
||||
|
||||
mutex_lock(&rcc->xo_lock);
|
||||
|
||||
value = rcc->xo_buffer_value | (QCOM_RPM_XO_MODE_ON << r->xo_offset);
|
||||
ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, clk_id, &value, 1);
|
||||
if (!ret) {
|
||||
r->enabled = true;
|
||||
rcc->xo_buffer_value = value;
|
||||
}
|
||||
|
||||
mutex_unlock(&rcc->xo_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void clk_rpm_xo_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_rpm *r = to_clk_rpm(hw);
|
||||
struct rpm_cc *rcc = r->rpm_cc;
|
||||
int ret, clk_id = r->rpm_clk_id;
|
||||
u32 value;
|
||||
|
||||
mutex_lock(&rcc->xo_lock);
|
||||
|
||||
value = rcc->xo_buffer_value & ~(QCOM_RPM_XO_MODE_ON << r->xo_offset);
|
||||
ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, clk_id, &value, 1);
|
||||
if (!ret) {
|
||||
r->enabled = false;
|
||||
rcc->xo_buffer_value = value;
|
||||
}
|
||||
|
||||
mutex_unlock(&rcc->xo_lock);
|
||||
}
|
||||
|
||||
static int clk_rpm_fixed_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_rpm *r = to_clk_rpm(hw);
|
||||
|
@ -378,6 +438,11 @@ static unsigned long clk_rpm_recalc_rate(struct clk_hw *hw,
|
|||
return r->rate;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_rpm_xo_ops = {
|
||||
.prepare = clk_rpm_xo_prepare,
|
||||
.unprepare = clk_rpm_xo_unprepare,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_rpm_fixed_ops = {
|
||||
.prepare = clk_rpm_fixed_prepare,
|
||||
.unprepare = clk_rpm_fixed_unprepare,
|
||||
|
@ -449,6 +514,11 @@ DEFINE_CLK_RPM(apq8064, mmfpb_clk, mmfpb_a_clk, QCOM_RPM_MMFPB_CLK);
|
|||
DEFINE_CLK_RPM(apq8064, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK);
|
||||
DEFINE_CLK_RPM(apq8064, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK);
|
||||
DEFINE_CLK_RPM(apq8064, qdss_clk, qdss_a_clk, QCOM_RPM_QDSS_CLK);
|
||||
DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_d0_clk, xo_d0_a_clk, 0);
|
||||
DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_d1_clk, xo_d1_a_clk, 8);
|
||||
DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a0_clk, xo_a0_a_clk, 16);
|
||||
DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a1_clk, xo_a1_a_clk, 24);
|
||||
DEFINE_CLK_RPM_XO_BUFFER(apq8064, xo_a2_clk, xo_a2_a_clk, 28);
|
||||
|
||||
static struct clk_rpm *apq8064_clks[] = {
|
||||
[RPM_APPS_FABRIC_CLK] = &apq8064_afab_clk,
|
||||
|
@ -469,6 +539,11 @@ static struct clk_rpm *apq8064_clks[] = {
|
|||
[RPM_SFPB_A_CLK] = &apq8064_sfpb_a_clk,
|
||||
[RPM_QDSS_CLK] = &apq8064_qdss_clk,
|
||||
[RPM_QDSS_A_CLK] = &apq8064_qdss_a_clk,
|
||||
[RPM_XO_D0] = &apq8064_xo_d0_clk,
|
||||
[RPM_XO_D1] = &apq8064_xo_d1_clk,
|
||||
[RPM_XO_A0] = &apq8064_xo_a0_clk,
|
||||
[RPM_XO_A1] = &apq8064_xo_a1_clk,
|
||||
[RPM_XO_A2] = &apq8064_xo_a2_clk,
|
||||
};
|
||||
|
||||
static const struct rpm_clk_desc rpm_clk_apq8064 = {
|
||||
|
@ -526,12 +601,14 @@ static int rpm_clk_probe(struct platform_device *pdev)
|
|||
|
||||
rcc->clks = rpm_clks;
|
||||
rcc->num_clks = num_clks;
|
||||
mutex_init(&rcc->xo_lock);
|
||||
|
||||
for (i = 0; i < num_clks; i++) {
|
||||
if (!rpm_clks[i])
|
||||
continue;
|
||||
|
||||
rpm_clks[i]->rpm = rpm;
|
||||
rpm_clks[i]->rpm_cc = rcc;
|
||||
|
||||
ret = clk_rpm_handoff(rpm_clks[i]);
|
||||
if (ret)
|
||||
|
|
|
@ -222,7 +222,13 @@
|
|||
#define CLK_TOP_APLL_DIV_PDN5 183
|
||||
#define CLK_TOP_APLL_DIV_PDN6 184
|
||||
#define CLK_TOP_APLL_DIV_PDN7 185
|
||||
#define CLK_TOP_NR_CLK 186
|
||||
#define CLK_TOP_APLL1_D3 186
|
||||
#define CLK_TOP_APLL1_REF_SEL 187
|
||||
#define CLK_TOP_APLL2_REF_SEL 188
|
||||
#define CLK_TOP_NFI2X_EN 189
|
||||
#define CLK_TOP_NFIECC_EN 190
|
||||
#define CLK_TOP_NFI1X_CK_EN 191
|
||||
#define CLK_TOP_NR_CLK 192
|
||||
|
||||
/* INFRACFG */
|
||||
|
||||
|
@ -281,7 +287,9 @@
|
|||
#define CLK_PERI_MSDC30_3_EN 41
|
||||
#define CLK_PERI_MSDC50_0_HCLK_EN 42
|
||||
#define CLK_PERI_MSDC50_3_HCLK_EN 43
|
||||
#define CLK_PERI_NR_CLK 44
|
||||
#define CLK_PERI_MSDC30_0_QTR_EN 44
|
||||
#define CLK_PERI_MSDC30_3_QTR_EN 45
|
||||
#define CLK_PERI_NR_CLK 46
|
||||
|
||||
/* MCUCFG */
|
||||
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
#define RPM_SMI_CLK 22
|
||||
#define RPM_SMI_A_CLK 23
|
||||
#define RPM_PLL4_CLK 24
|
||||
#define RPM_XO_D0 25
|
||||
#define RPM_XO_D1 26
|
||||
#define RPM_XO_A0 27
|
||||
#define RPM_XO_A1 28
|
||||
#define RPM_XO_A2 29
|
||||
|
||||
/* SMD RPM clocks */
|
||||
#define RPM_SMD_XO_CLK_SRC 0
|
||||
|
|
Loading…
Reference in a new issue