Merge branch 'clk-qcom' into clk-next

* clk-qcom:
  clk: qcom: clk-smd-rpm: add msm8996 rpmclks
  clk: qcom: Implement RPM clocks for MSM8660/APQ8060
  clk: qcom: Update DT bindings for the MSM8660/APQ8060 RPMCC
  clk: qcom: Elaborate on "active" clocks in the RPM clock bindings
  clk: qcom: Remove unused RCG ops
This commit is contained in:
Stephen Boyd 2017-11-14 10:07:42 -08:00
commit 8f62040086
7 changed files with 207 additions and 82 deletions

View File

@ -10,12 +10,23 @@ Required properties :
- compatible : shall contain only one of the following. The generic
compatible "qcom,rpmcc" should be also included.
"qcom,rpmcc-msm8660", "qcom,rpmcc"
"qcom,rpmcc-apq8060", "qcom,rpmcc"
"qcom,rpmcc-msm8916", "qcom,rpmcc"
"qcom,rpmcc-msm8974", "qcom,rpmcc"
"qcom,rpmcc-apq8064", "qcom,rpmcc"
"qcom,rpmcc-msm8996", "qcom,rpmcc"
- #clock-cells : shall contain 1
The clock enumerators are defined in <dt-bindings/clock/qcom,rpmcc.h>
and come in pairs: FOO_CLK followed by FOO_A_CLK. The latter clock
is an "active" clock, which means that the consumer only care that the
clock is available when the apps CPU subsystem is active, i.e. not
suspended or in deep idle. If it is important that the clock keeps running
during system suspend, you need to specify the non-active clock, the one
not containing *_A_* in the enumerator name.
Example:
smd {
compatible = "qcom,smd";

View File

@ -156,7 +156,6 @@ extern const struct clk_ops clk_dyn_rcg_ops;
* @hid_width: number of bits in half integer divider
* @parent_map: map from software's parent index to hardware's src_sel field
* @freq_tbl: frequency table
* @current_freq: last cached frequency when using branches with shared RCGs
* @clkr: regmap clock handle
*
*/
@ -166,7 +165,6 @@ struct clk_rcg2 {
u8 hid_width;
const struct parent_map *parent_map;
const struct freq_tbl *freq_tbl;
unsigned long current_freq;
struct clk_regmap clkr;
};
@ -174,7 +172,6 @@ struct clk_rcg2 {
extern const struct clk_ops clk_rcg2_ops;
extern const struct clk_ops clk_rcg2_floor_ops;
extern const struct clk_ops clk_rcg2_shared_ops;
extern const struct clk_ops clk_edp_pixel_ops;
extern const struct clk_ops clk_byte_ops;
extern const struct clk_ops clk_byte2_ops;

View File

@ -358,85 +358,6 @@ const struct clk_ops clk_rcg2_floor_ops = {
};
EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops);
static int clk_rcg2_shared_force_enable(struct clk_hw *hw, unsigned long rate)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
const char *name = clk_hw_get_name(hw);
int ret, count;
/* force enable RCG */
ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
CMD_ROOT_EN, CMD_ROOT_EN);
if (ret)
return ret;
/* wait for RCG to turn ON */
for (count = 500; count > 0; count--) {
ret = clk_rcg2_is_enabled(hw);
if (ret)
break;
udelay(1);
}
if (!count)
pr_err("%s: RCG did not turn on\n", name);
/* set clock rate */
ret = __clk_rcg2_set_rate(hw, rate, CEIL);
if (ret)
return ret;
/* clear force enable RCG */
return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
CMD_ROOT_EN, 0);
}
static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
/* cache the rate */
rcg->current_freq = rate;
if (!__clk_is_enabled(hw->clk))
return 0;
return clk_rcg2_shared_force_enable(hw, rcg->current_freq);
}
static unsigned long
clk_rcg2_shared_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
return rcg->current_freq = clk_rcg2_recalc_rate(hw, parent_rate);
}
static int clk_rcg2_shared_enable(struct clk_hw *hw)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
return clk_rcg2_shared_force_enable(hw, rcg->current_freq);
}
static void clk_rcg2_shared_disable(struct clk_hw *hw)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
/* switch to XO, which is the lowest entry in the freq table */
clk_rcg2_shared_set_rate(hw, rcg->freq_tbl[0].freq, 0);
}
const struct clk_ops clk_rcg2_shared_ops = {
.enable = clk_rcg2_shared_enable,
.disable = clk_rcg2_shared_disable,
.get_parent = clk_rcg2_get_parent,
.recalc_rate = clk_rcg2_shared_recalc_rate,
.determine_rate = clk_rcg2_determine_rate,
.set_rate = clk_rcg2_shared_set_rate,
};
EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
struct frac_entry {
int num;
int den;

View File

@ -56,6 +56,18 @@
}, \
}
#define DEFINE_CLK_RPM_FIXED(_platform, _name, _active, r_id, r) \
static struct clk_rpm _platform##_##_name = { \
.rpm_clk_id = (r_id), \
.rate = (r), \
.hw.init = &(struct clk_init_data){ \
.ops = &clk_rpm_fixed_ops, \
.name = #_name, \
.parent_names = (const char *[]){ "pxo" }, \
.num_parents = 1, \
}, \
}
#define DEFINE_CLK_RPM_PXO_BRANCH(_platform, _name, _active, r_id, r) \
static struct clk_rpm _platform##_##_active; \
static struct clk_rpm _platform##_##_name = { \
@ -143,6 +155,13 @@ static int clk_rpm_handoff(struct clk_rpm *r)
int ret;
u32 value = INT_MAX;
/*
* The vendor tree simply reads the status for this
* RPM clock.
*/
if (r->rpm_clk_id == QCOM_RPM_PLL_4)
return 0;
ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
r->rpm_clk_id, &value, 1);
if (ret)
@ -269,6 +288,32 @@ out:
mutex_unlock(&rpm_clk_lock);
}
static int clk_rpm_fixed_prepare(struct clk_hw *hw)
{
struct clk_rpm *r = to_clk_rpm(hw);
u32 value = 1;
int ret;
ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
r->rpm_clk_id, &value, 1);
if (!ret)
r->enabled = true;
return ret;
}
static void clk_rpm_fixed_unprepare(struct clk_hw *hw)
{
struct clk_rpm *r = to_clk_rpm(hw);
u32 value = 0;
int ret;
ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
r->rpm_clk_id, &value, 1);
if (!ret)
r->enabled = false;
}
static int clk_rpm_set_rate(struct clk_hw *hw,
unsigned long rate, unsigned long parent_rate)
{
@ -333,6 +378,13 @@ static unsigned long clk_rpm_recalc_rate(struct clk_hw *hw,
return r->rate;
}
static const struct clk_ops clk_rpm_fixed_ops = {
.prepare = clk_rpm_fixed_prepare,
.unprepare = clk_rpm_fixed_unprepare,
.round_rate = clk_rpm_round_rate,
.recalc_rate = clk_rpm_recalc_rate,
};
static const struct clk_ops clk_rpm_ops = {
.prepare = clk_rpm_prepare,
.unprepare = clk_rpm_unprepare,
@ -348,6 +400,45 @@ static const struct clk_ops clk_rpm_branch_ops = {
.recalc_rate = clk_rpm_recalc_rate,
};
/* MSM8660/APQ8060 */
DEFINE_CLK_RPM(msm8660, afab_clk, afab_a_clk, QCOM_RPM_APPS_FABRIC_CLK);
DEFINE_CLK_RPM(msm8660, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK);
DEFINE_CLK_RPM(msm8660, mmfab_clk, mmfab_a_clk, QCOM_RPM_MM_FABRIC_CLK);
DEFINE_CLK_RPM(msm8660, daytona_clk, daytona_a_clk, QCOM_RPM_DAYTONA_FABRIC_CLK);
DEFINE_CLK_RPM(msm8660, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK);
DEFINE_CLK_RPM(msm8660, cfpb_clk, cfpb_a_clk, QCOM_RPM_CFPB_CLK);
DEFINE_CLK_RPM(msm8660, mmfpb_clk, mmfpb_a_clk, QCOM_RPM_MMFPB_CLK);
DEFINE_CLK_RPM(msm8660, smi_clk, smi_a_clk, QCOM_RPM_SMI_CLK);
DEFINE_CLK_RPM(msm8660, ebi1_clk, ebi1_a_clk, QCOM_RPM_EBI1_CLK);
DEFINE_CLK_RPM_FIXED(msm8660, pll4_clk, pll4_a_clk, QCOM_RPM_PLL_4, 540672000);
static struct clk_rpm *msm8660_clks[] = {
[RPM_APPS_FABRIC_CLK] = &msm8660_afab_clk,
[RPM_APPS_FABRIC_A_CLK] = &msm8660_afab_a_clk,
[RPM_SYS_FABRIC_CLK] = &msm8660_sfab_clk,
[RPM_SYS_FABRIC_A_CLK] = &msm8660_sfab_a_clk,
[RPM_MM_FABRIC_CLK] = &msm8660_mmfab_clk,
[RPM_MM_FABRIC_A_CLK] = &msm8660_mmfab_a_clk,
[RPM_DAYTONA_FABRIC_CLK] = &msm8660_daytona_clk,
[RPM_DAYTONA_FABRIC_A_CLK] = &msm8660_daytona_a_clk,
[RPM_SFPB_CLK] = &msm8660_sfpb_clk,
[RPM_SFPB_A_CLK] = &msm8660_sfpb_a_clk,
[RPM_CFPB_CLK] = &msm8660_cfpb_clk,
[RPM_CFPB_A_CLK] = &msm8660_cfpb_a_clk,
[RPM_MMFPB_CLK] = &msm8660_mmfpb_clk,
[RPM_MMFPB_A_CLK] = &msm8660_mmfpb_a_clk,
[RPM_SMI_CLK] = &msm8660_smi_clk,
[RPM_SMI_A_CLK] = &msm8660_smi_a_clk,
[RPM_EBI1_CLK] = &msm8660_ebi1_clk,
[RPM_EBI1_A_CLK] = &msm8660_ebi1_a_clk,
[RPM_PLL4_CLK] = &msm8660_pll4_clk,
};
static const struct rpm_clk_desc rpm_clk_msm8660 = {
.clks = msm8660_clks,
.num_clks = ARRAY_SIZE(msm8660_clks),
};
/* apq8064 */
DEFINE_CLK_RPM(apq8064, afab_clk, afab_a_clk, QCOM_RPM_APPS_FABRIC_CLK);
DEFINE_CLK_RPM(apq8064, cfpb_clk, cfpb_a_clk, QCOM_RPM_CFPB_CLK);
@ -386,6 +477,8 @@ static const struct rpm_clk_desc rpm_clk_apq8064 = {
};
static const struct of_device_id rpm_clk_match_table[] = {
{ .compatible = "qcom,rpmcc-msm8660", .data = &rpm_clk_msm8660 },
{ .compatible = "qcom,rpmcc-apq8060", .data = &rpm_clk_msm8660 },
{ .compatible = "qcom,rpmcc-apq8064", .data = &rpm_clk_apq8064 },
{ }
};

View File

@ -530,9 +530,91 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8974 = {
.clks = msm8974_clks,
.num_clks = ARRAY_SIZE(msm8974_clks),
};
/* msm8996 */
DEFINE_CLK_SMD_RPM(msm8996, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
DEFINE_CLK_SMD_RPM(msm8996, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
DEFINE_CLK_SMD_RPM(msm8996, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
DEFINE_CLK_SMD_RPM(msm8996, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
DEFINE_CLK_SMD_RPM(msm8996, mmssnoc_axi_rpm_clk, mmssnoc_axi_rpm_a_clk,
QCOM_SMD_RPM_MMAXI_CLK, 0);
DEFINE_CLK_SMD_RPM(msm8996, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0);
DEFINE_CLK_SMD_RPM(msm8996, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0);
DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre1_noc_clk, aggre1_noc_a_clk,
QCOM_SMD_RPM_AGGR_CLK, 1, 1000);
DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre2_noc_clk, aggre2_noc_a_clk,
QCOM_SMD_RPM_AGGR_CLK, 2, 1000);
DEFINE_CLK_SMD_RPM_QDSS(msm8996, qdss_clk, qdss_a_clk,
QCOM_SMD_RPM_MISC_CLK, 1);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, bb_clk1, bb_clk1_a, 1);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, bb_clk2, bb_clk2_a, 2);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, rf_clk1, rf_clk1_a, 4);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, rf_clk2, rf_clk2_a, 5);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, ln_bb_clk, ln_bb_a_clk, 8);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk1, div_clk1_a, 0xb);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk2, div_clk2_a, 0xc);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk3, div_clk3_a, 0xd);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk1_pin, bb_clk1_a_pin, 1);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk2_pin, bb_clk2_a_pin, 2);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk1_pin, rf_clk1_a_pin, 4);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk2_pin, rf_clk2_a_pin, 5);
static struct clk_smd_rpm *msm8996_clks[] = {
[RPM_SMD_PCNOC_CLK] = &msm8996_pcnoc_clk,
[RPM_SMD_PCNOC_A_CLK] = &msm8996_pcnoc_a_clk,
[RPM_SMD_SNOC_CLK] = &msm8996_snoc_clk,
[RPM_SMD_SNOC_A_CLK] = &msm8996_snoc_a_clk,
[RPM_SMD_CNOC_CLK] = &msm8996_cnoc_clk,
[RPM_SMD_CNOC_A_CLK] = &msm8996_cnoc_a_clk,
[RPM_SMD_BIMC_CLK] = &msm8996_bimc_clk,
[RPM_SMD_BIMC_A_CLK] = &msm8996_bimc_a_clk,
[RPM_SMD_MMAXI_CLK] = &msm8996_mmssnoc_axi_rpm_clk,
[RPM_SMD_MMAXI_A_CLK] = &msm8996_mmssnoc_axi_rpm_a_clk,
[RPM_SMD_IPA_CLK] = &msm8996_ipa_clk,
[RPM_SMD_IPA_A_CLK] = &msm8996_ipa_a_clk,
[RPM_SMD_CE1_CLK] = &msm8996_ce1_clk,
[RPM_SMD_CE1_A_CLK] = &msm8996_ce1_a_clk,
[RPM_SMD_AGGR1_NOC_CLK] = &msm8996_aggre1_noc_clk,
[RPM_SMD_AGGR1_NOC_A_CLK] = &msm8996_aggre1_noc_a_clk,
[RPM_SMD_AGGR2_NOC_CLK] = &msm8996_aggre2_noc_clk,
[RPM_SMD_AGGR2_NOC_A_CLK] = &msm8996_aggre2_noc_a_clk,
[RPM_SMD_QDSS_CLK] = &msm8996_qdss_clk,
[RPM_SMD_QDSS_A_CLK] = &msm8996_qdss_a_clk,
[RPM_SMD_BB_CLK1] = &msm8996_bb_clk1,
[RPM_SMD_BB_CLK1_A] = &msm8996_bb_clk1_a,
[RPM_SMD_BB_CLK2] = &msm8996_bb_clk2,
[RPM_SMD_BB_CLK2_A] = &msm8996_bb_clk2_a,
[RPM_SMD_RF_CLK1] = &msm8996_rf_clk1,
[RPM_SMD_RF_CLK1_A] = &msm8996_rf_clk1_a,
[RPM_SMD_RF_CLK2] = &msm8996_rf_clk2,
[RPM_SMD_RF_CLK2_A] = &msm8996_rf_clk2_a,
[RPM_SMD_LN_BB_CLK] = &msm8996_ln_bb_clk,
[RPM_SMD_LN_BB_A_CLK] = &msm8996_ln_bb_a_clk,
[RPM_SMD_DIV_CLK1] = &msm8996_div_clk1,
[RPM_SMD_DIV_A_CLK1] = &msm8996_div_clk1_a,
[RPM_SMD_DIV_CLK2] = &msm8996_div_clk2,
[RPM_SMD_DIV_A_CLK2] = &msm8996_div_clk2_a,
[RPM_SMD_DIV_CLK3] = &msm8996_div_clk3,
[RPM_SMD_DIV_A_CLK3] = &msm8996_div_clk3_a,
[RPM_SMD_BB_CLK1_PIN] = &msm8996_bb_clk1_pin,
[RPM_SMD_BB_CLK1_A_PIN] = &msm8996_bb_clk1_a_pin,
[RPM_SMD_BB_CLK2_PIN] = &msm8996_bb_clk2_pin,
[RPM_SMD_BB_CLK2_A_PIN] = &msm8996_bb_clk2_a_pin,
[RPM_SMD_RF_CLK1_PIN] = &msm8996_rf_clk1_pin,
[RPM_SMD_RF_CLK1_A_PIN] = &msm8996_rf_clk1_a_pin,
[RPM_SMD_RF_CLK2_PIN] = &msm8996_rf_clk2_pin,
[RPM_SMD_RF_CLK2_A_PIN] = &msm8996_rf_clk2_a_pin,
};
static const struct rpm_smd_clk_desc rpm_clk_msm8996 = {
.clks = msm8996_clks,
.num_clks = ARRAY_SIZE(msm8996_clks),
};
static const struct of_device_id rpm_smd_clk_match_table[] = {
{ .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
{ .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
{ .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 },
{ }
};
MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);

View File

@ -37,6 +37,9 @@
#define RPM_SYS_FABRIC_A_CLK 19
#define RPM_SFPB_CLK 20
#define RPM_SFPB_A_CLK 21
#define RPM_SMI_CLK 22
#define RPM_SMI_A_CLK 23
#define RPM_PLL4_CLK 24
/* SMD RPM clocks */
#define RPM_SMD_XO_CLK_SRC 0
@ -101,5 +104,19 @@
#define RPM_SMD_CXO_A1_A_PIN 59
#define RPM_SMD_CXO_A2_PIN 60
#define RPM_SMD_CXO_A2_A_PIN 61
#define RPM_SMD_AGGR1_NOC_CLK 62
#define RPM_SMD_AGGR1_NOC_A_CLK 63
#define RPM_SMD_AGGR2_NOC_CLK 64
#define RPM_SMD_AGGR2_NOC_A_CLK 65
#define RPM_SMD_MMAXI_CLK 66
#define RPM_SMD_MMAXI_A_CLK 67
#define RPM_SMD_IPA_CLK 68
#define RPM_SMD_IPA_A_CLK 69
#define RPM_SMD_CE1_CLK 70
#define RPM_SMD_CE1_A_CLK 71
#define RPM_SMD_DIV_CLK3 72
#define RPM_SMD_DIV_A_CLK3 73
#define RPM_SMD_LN_BB_CLK 74
#define RPM_SMD_LN_BB_A_CLK 75
#endif

View File

@ -26,6 +26,10 @@ struct qcom_smd_rpm;
#define QCOM_SMD_RPM_SMPB 0x62706d73
#define QCOM_SMD_RPM_SPDM 0x63707362
#define QCOM_SMD_RPM_VSA 0x00617376
#define QCOM_SMD_RPM_MMAXI_CLK 0x69786d6d
#define QCOM_SMD_RPM_IPA_CLK 0x617069
#define QCOM_SMD_RPM_CE_CLK 0x6563
#define QCOM_SMD_RPM_AGGR_CLK 0x72676761
int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
int state,