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:
Stephen Boyd
2018-04-06 13:21:52 -07:00
8 changed files with 202 additions and 80 deletions

View File

@@ -2311,8 +2311,11 @@ static int clk_core_set_phase_nolock(struct clk_core *core, int degrees)
trace_clk_set_phase(core, 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); ret = core->ops->set_phase(core->hw, degrees);
if (!ret)
core->phase = degrees;
}
trace_clk_set_phase_complete(core, degrees); trace_clk_set_phase_complete(core, degrees);
@@ -2372,6 +2375,9 @@ static int clk_core_get_phase(struct clk_core *core)
int ret; int ret;
clk_prepare_lock(); 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; ret = core->phase;
clk_prepare_unlock(); clk_prepare_unlock();

View File

@@ -221,6 +221,8 @@ static const struct mtk_fixed_factor top_divs[] = {
4), 4),
FACTOR(CLK_TOP_D2A_ULCLK_6P5M, "d2a_ulclk_6p5m", "clk26m", 1, FACTOR(CLK_TOP_D2A_ULCLK_6P5M, "d2a_ulclk_6p5m", "clk26m", 1,
4), 4),
FACTOR(CLK_TOP_APLL1_D3, "apll1_d3", "apll1_ck", 1,
3),
}; };
static const char * const axi_parents[] = { static const char * const axi_parents[] = {
@@ -625,7 +627,7 @@ static const char * const ether_125m_parents[] = {
static const char * const ether_50m_parents[] = { static const char * const ether_50m_parents[] = {
"clk26m", "clk26m",
"etherpll_50m", "etherpll_50m",
"univpll_d26", "apll1_d3",
"univpll3_d4" "univpll3_d4"
}; };
@@ -686,7 +688,7 @@ static const char * const i2c_parents[] = {
static const char * const msdc0p_aes_parents[] = { static const char * const msdc0p_aes_parents[] = {
"clk26m", "clk26m",
"msdcpll_ck", "syspll_d2",
"univpll_d3", "univpll_d3",
"vcodecpll_ck" "vcodecpll_ck"
}; };
@@ -719,6 +721,17 @@ static const char * const aud_apll2_parents[] = {
"clkaud_ext_i_2" "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[] = { static const char * const audull_vtx_parents[] = {
"d2a_ulclk_6p5m", "d2a_ulclk_6p5m",
"clkaud_ext_i_0" "clkaud_ext_i_0"
@@ -886,6 +899,10 @@ static struct mtk_composite top_muxes[] = {
aud_apll2_parents, 0x134, 1, 1), aud_apll2_parents, 0x134, 1, 1),
MUX(CLK_TOP_DA_AUDULL_VTX_6P5M_SEL, "audull_vtx_sel", MUX(CLK_TOP_DA_AUDULL_VTX_6P5M_SEL, "audull_vtx_sel",
audull_vtx_parents, 0x134, 31, 1), 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[] = { 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), 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, .set_ofs = 0x120,
.clr_ofs = 0x120, .clr_ofs = 0x120,
.sta_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, \ .id = _id, \
.name = _name, \ .name = _name, \
.parent_name = _parent, \ .parent_name = _parent, \
.regs = &top_cg_regs, \ .regs = &top0_cg_regs, \
.shift = _shift, \ .shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr, \ .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[] = { static const struct mtk_gate top_clks[] = {
GATE_TOP(CLK_TOP_APLL_DIV_PDN0, "apll_div_pdn0", "i2so1_sel", 0), /* TOP0 */
GATE_TOP(CLK_TOP_APLL_DIV_PDN1, "apll_div_pdn1", "i2so2_sel", 1), GATE_TOP0(CLK_TOP_APLL_DIV_PDN0, "apll_div_pdn0", "i2so1_sel", 0),
GATE_TOP(CLK_TOP_APLL_DIV_PDN2, "apll_div_pdn2", "i2so3_sel", 2), GATE_TOP0(CLK_TOP_APLL_DIV_PDN1, "apll_div_pdn1", "i2so2_sel", 1),
GATE_TOP(CLK_TOP_APLL_DIV_PDN3, "apll_div_pdn3", "tdmo0_sel", 3), GATE_TOP0(CLK_TOP_APLL_DIV_PDN2, "apll_div_pdn2", "i2so3_sel", 2),
GATE_TOP(CLK_TOP_APLL_DIV_PDN4, "apll_div_pdn4", "tdmo1_sel", 4), GATE_TOP0(CLK_TOP_APLL_DIV_PDN3, "apll_div_pdn3", "tdmo0_sel", 3),
GATE_TOP(CLK_TOP_APLL_DIV_PDN5, "apll_div_pdn5", "i2si1_sel", 5), GATE_TOP0(CLK_TOP_APLL_DIV_PDN4, "apll_div_pdn4", "tdmo1_sel", 4),
GATE_TOP(CLK_TOP_APLL_DIV_PDN6, "apll_div_pdn6", "i2si2_sel", 6), GATE_TOP0(CLK_TOP_APLL_DIV_PDN5, "apll_div_pdn5", "i2si1_sel", 5),
GATE_TOP(CLK_TOP_APLL_DIV_PDN7, "apll_div_pdn7", "i2si3_sel", 7), 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 = { static const struct mtk_gate_regs infra_cg_regs = {
.set_ofs = 0x40, .set_ofs = 0x40,
.clr_ofs = 0x44, .clr_ofs = 0x44,
.sta_ofs = 0x40, .sta_ofs = 0x48,
}; };
#define GATE_INFRA(_id, _name, _parent, _shift) { \ #define GATE_INFRA(_id, _name, _parent, _shift) { \
@@ -1120,6 +1157,10 @@ static const struct mtk_gate peri_clks[] = {
"msdc50_0_h_sel", 4), "msdc50_0_h_sel", 4),
GATE_PERI2(CLK_PERI_MSDC50_3_HCLK_EN, "per_msdc50_3_h", GATE_PERI2(CLK_PERI_MSDC50_3_HCLK_EN, "per_msdc50_3_h",
"msdc50_3_h_sel", 5), "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) #define MT2712_PLL_FMAX (3000UL * MHZ)

View File

@@ -46,11 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem *sar)
} }
static const u32 armada_38x_cpu_frequencies[] __initconst = { static const u32 armada_38x_cpu_frequencies[] __initconst = {
0, 0, 0, 0, 666 * 1000 * 1000, 0, 800 * 1000 * 1000, 0,
1066 * 1000 * 1000, 0, 0, 0, 1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0,
1332 * 1000 * 1000, 0, 0, 0, 1332 * 1000 * 1000, 0, 0, 0,
1600 * 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) 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 = { static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {1, 2}, {0, 1}, {1, 2}, {0, 1},
{1, 2}, {0, 1}, {0, 1}, {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}, {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}, {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}, {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}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},

View File

@@ -13,18 +13,17 @@
/* /*
* CP110 has 6 core clocks: * CP110 has 6 core clocks:
* *
* - APLL (1 Ghz) * - PLL0 (1 Ghz)
* - PPv2 core (1/3 APLL) * - PPv2 core (1/3 PLL0)
* - EIP (1/2 APLL) * - x2 Core (1/2 PLL0)
* - Core (1/2 EIP) * - Core (1/2 x2 Core)
* - SDIO (2/5 APLL) * - SDIO (2/5 PLL0)
* *
* - NAND clock, which is either: * - NAND clock, which is either:
* - Equal to SDIO clock * - Equal to SDIO clock
* - 2/5 APLL * - 2/5 PLL0
* *
* CP110 has 32 gatable clocks, for the various peripherals in the * CP110 has 32 gatable clocks, for the various peripherals in the IP.
* IP. They have fairly complicated parent/child relationships.
*/ */
#define pr_fmt(fmt) "cp110-system-controller: " fmt #define pr_fmt(fmt) "cp110-system-controller: " fmt
@@ -53,9 +52,9 @@ enum {
#define CP110_CLK_NUM \ #define CP110_CLK_NUM \
(CP110_MAX_CORE_CLOCKS + CP110_MAX_GATABLE_CLOCKS) (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_PPV2 1
#define CP110_CORE_EIP 2 #define CP110_CORE_X2CORE 2
#define CP110_CORE_CORE 3 #define CP110_CORE_CORE 3
#define CP110_CORE_NAND 4 #define CP110_CORE_NAND 4
#define CP110_CORE_SDIO 5 #define CP110_CORE_SDIO 5
@@ -237,7 +236,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
struct regmap *regmap; struct regmap *regmap;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; 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; *sdio_name;
struct clk_hw_onecell_data *cp110_clk_data; struct clk_hw_onecell_data *cp110_clk_data;
struct clk_hw *hw, **cp110_clks; 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_clks = cp110_clk_data->hws;
cp110_clk_data->num = CP110_CLK_NUM; cp110_clk_data->num = CP110_CLK_NUM;
/* Register the APLL which is the root of the hw tree */ /* Register the PLL0 which is the root of the hw tree */
apll_name = cp110_unique_name(dev, syscon_node, "apll"); pll0_name = cp110_unique_name(dev, syscon_node, "pll0");
hw = clk_hw_register_fixed_rate(NULL, apll_name, NULL, 0, hw = clk_hw_register_fixed_rate(NULL, pll0_name, NULL, 0,
1000 * 1000 * 1000); 1000 * 1000 * 1000);
if (IS_ERR(hw)) { if (IS_ERR(hw)) {
ret = PTR_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"); 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)) { if (IS_ERR(hw)) {
ret = PTR_ERR(hw); ret = PTR_ERR(hw);
goto fail_ppv2; goto fail_ppv2;
@@ -284,30 +283,32 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
cp110_clks[CP110_CORE_PPV2] = hw; cp110_clks[CP110_CORE_PPV2] = hw;
/* EIP clock is APLL/2 */ /* X2CORE clock is PLL0/2 */
eip_name = cp110_unique_name(dev, syscon_node, "eip"); x2core_name = cp110_unique_name(dev, syscon_node, "x2core");
hw = clk_hw_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2); hw = clk_hw_register_fixed_factor(NULL, x2core_name, pll0_name,
0, 1, 2);
if (IS_ERR(hw)) { if (IS_ERR(hw)) {
ret = PTR_ERR(hw); ret = PTR_ERR(hw);
goto fail_eip; 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"); 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)) { if (IS_ERR(hw)) {
ret = PTR_ERR(hw); ret = PTR_ERR(hw);
goto fail_core; goto fail_core;
} }
cp110_clks[CP110_CORE_CORE] = hw; 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"); nand_name = cp110_unique_name(dev, syscon_node, "nand-core");
if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK) if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK)
hw = clk_hw_register_fixed_factor(NULL, nand_name, hw = clk_hw_register_fixed_factor(NULL, nand_name,
apll_name, 0, 2, 5); pll0_name, 0, 2, 5);
else else
hw = clk_hw_register_fixed_factor(NULL, nand_name, hw = clk_hw_register_fixed_factor(NULL, nand_name,
core_name, 0, 1, 1); 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; 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"); sdio_name = cp110_unique_name(dev, syscon_node, "sdio-core");
hw = clk_hw_register_fixed_factor(NULL, sdio_name, hw = clk_hw_register_fixed_factor(NULL, sdio_name,
apll_name, 0, 2, 5); pll0_name, 0, 2, 5);
if (IS_ERR(hw)) { if (IS_ERR(hw)) {
ret = PTR_ERR(hw); ret = PTR_ERR(hw);
goto fail_sdio; goto fail_sdio;
@@ -341,40 +342,23 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
continue; continue;
switch (i) { 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: case CP110_GATE_NAND:
parent = nand_name; parent = nand_name;
break; break;
case CP110_GATE_MG:
case CP110_GATE_GOP_DP:
case CP110_GATE_PPV2: case CP110_GATE_PPV2:
parent = ppv2_name; parent = ppv2_name;
break; break;
case CP110_GATE_SDIO: case CP110_GATE_SDIO:
parent = sdio_name; parent = sdio_name;
break; break;
case CP110_GATE_GOP_DP: case CP110_GATE_MAIN:
parent = gate_name[CP110_GATE_SDMMC_GOP]; case CP110_GATE_PCIE_XOR:
break;
case CP110_GATE_XOR1:
case CP110_GATE_XOR0:
case CP110_GATE_PCIE_X1_0:
case CP110_GATE_PCIE_X1_1:
case CP110_GATE_PCIE_X4: case CP110_GATE_PCIE_X4:
parent = gate_name[CP110_GATE_PCIE_XOR]; case CP110_GATE_EIP150:
break; case CP110_GATE_EIP197:
case CP110_GATE_SATA: parent = x2core_name;
case CP110_GATE_USB3H0:
case CP110_GATE_USB3H1:
case CP110_GATE_USB3DEV:
parent = gate_name[CP110_GATE_SATA_USB];
break; break;
default: default:
parent = core_name; parent = core_name;
@@ -413,12 +397,12 @@ fail_sdio:
fail_nand: fail_nand:
clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]); clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]);
fail_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: fail_eip:
clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]); clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]);
fail_ppv2: fail_ppv2:
clk_hw_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]); clk_hw_unregister_fixed_rate(cp110_clks[CP110_CORE_PLL0]);
fail_apll: fail_pll0:
return ret; return ret;
} }

View File

@@ -67,6 +67,7 @@
#define LPC32XX_USB_CLK_STS 0xF8 #define LPC32XX_USB_CLK_STS 0xF8
static struct regmap_config lpc32xx_scb_regmap_config = { static struct regmap_config lpc32xx_scb_regmap_config = {
.name = "scb",
.reg_bits = 32, .reg_bits = 32,
.val_bits = 32, .val_bits = 32,
.reg_stride = 4, .reg_stride = 4,

View File

@@ -29,6 +29,7 @@
#define QCOM_RPM_MISC_CLK_TYPE 0x306b6c63 #define QCOM_RPM_MISC_CLK_TYPE 0x306b6c63
#define QCOM_RPM_SCALING_ENABLE_ID 0x2 #define QCOM_RPM_SCALING_ENABLE_ID 0x2
#define QCOM_RPM_XO_MODE_ON 0x2
#define DEFINE_CLK_RPM(_platform, _name, _active, r_id) \ #define DEFINE_CLK_RPM(_platform, _name, _active, r_id) \
static struct clk_rpm _platform##_##_active; \ 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) \ #define DEFINE_CLK_RPM_FIXED(_platform, _name, _active, r_id, r) \
static struct clk_rpm _platform##_##_name = { \ static struct clk_rpm _platform##_##_name = { \
.rpm_clk_id = (r_id), \ .rpm_clk_id = (r_id), \
@@ -126,8 +139,11 @@
#define to_clk_rpm(_hw) container_of(_hw, struct clk_rpm, hw) #define to_clk_rpm(_hw) container_of(_hw, struct clk_rpm, hw)
struct rpm_cc;
struct clk_rpm { struct clk_rpm {
const int rpm_clk_id; const int rpm_clk_id;
const int xo_offset;
const bool active_only; const bool active_only;
unsigned long rate; unsigned long rate;
bool enabled; bool enabled;
@@ -135,12 +151,15 @@ struct clk_rpm {
struct clk_rpm *peer; struct clk_rpm *peer;
struct clk_hw hw; struct clk_hw hw;
struct qcom_rpm *rpm; struct qcom_rpm *rpm;
struct rpm_cc *rpm_cc;
}; };
struct rpm_cc { struct rpm_cc {
struct qcom_rpm *rpm; struct qcom_rpm *rpm;
struct clk_rpm **clks; struct clk_rpm **clks;
size_t num_clks; size_t num_clks;
u32 xo_buffer_value;
struct mutex xo_lock;
}; };
struct rpm_clk_desc { 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 * The vendor tree simply reads the status for this
* RPM clock. * 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; return 0;
ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE, ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
@@ -288,6 +308,46 @@ out:
mutex_unlock(&rpm_clk_lock); 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) static int clk_rpm_fixed_prepare(struct clk_hw *hw)
{ {
struct clk_rpm *r = to_clk_rpm(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; 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 = { static const struct clk_ops clk_rpm_fixed_ops = {
.prepare = clk_rpm_fixed_prepare, .prepare = clk_rpm_fixed_prepare,
.unprepare = clk_rpm_fixed_unprepare, .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, 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, 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(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[] = { static struct clk_rpm *apq8064_clks[] = {
[RPM_APPS_FABRIC_CLK] = &apq8064_afab_clk, [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_SFPB_A_CLK] = &apq8064_sfpb_a_clk,
[RPM_QDSS_CLK] = &apq8064_qdss_clk, [RPM_QDSS_CLK] = &apq8064_qdss_clk,
[RPM_QDSS_A_CLK] = &apq8064_qdss_a_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 = { 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->clks = rpm_clks;
rcc->num_clks = num_clks; rcc->num_clks = num_clks;
mutex_init(&rcc->xo_lock);
for (i = 0; i < num_clks; i++) { for (i = 0; i < num_clks; i++) {
if (!rpm_clks[i]) if (!rpm_clks[i])
continue; continue;
rpm_clks[i]->rpm = rpm; rpm_clks[i]->rpm = rpm;
rpm_clks[i]->rpm_cc = rcc;
ret = clk_rpm_handoff(rpm_clks[i]); ret = clk_rpm_handoff(rpm_clks[i]);
if (ret) if (ret)

View File

@@ -222,7 +222,13 @@
#define CLK_TOP_APLL_DIV_PDN5 183 #define CLK_TOP_APLL_DIV_PDN5 183
#define CLK_TOP_APLL_DIV_PDN6 184 #define CLK_TOP_APLL_DIV_PDN6 184
#define CLK_TOP_APLL_DIV_PDN7 185 #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 */ /* INFRACFG */
@@ -281,7 +287,9 @@
#define CLK_PERI_MSDC30_3_EN 41 #define CLK_PERI_MSDC30_3_EN 41
#define CLK_PERI_MSDC50_0_HCLK_EN 42 #define CLK_PERI_MSDC50_0_HCLK_EN 42
#define CLK_PERI_MSDC50_3_HCLK_EN 43 #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 */ /* MCUCFG */

View File

@@ -40,6 +40,11 @@
#define RPM_SMI_CLK 22 #define RPM_SMI_CLK 22
#define RPM_SMI_A_CLK 23 #define RPM_SMI_A_CLK 23
#define RPM_PLL4_CLK 24 #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 */ /* SMD RPM clocks */
#define RPM_SMD_XO_CLK_SRC 0 #define RPM_SMD_XO_CLK_SRC 0