Skip to content

Commit

Permalink
Merge branch 'clk-qcom' into clk-next
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
bebarino committed Nov 14, 2017
2 parents 7a103f0 + 7066fdd commit 8f62040
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 82 deletions.
11 changes: 11 additions & 0 deletions Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
3 changes: 0 additions & 3 deletions drivers/clk/qcom/clk-rcg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
*/
Expand All @@ -166,15 +165,13 @@ 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;
};

#define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)

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;
Expand Down
79 changes: 0 additions & 79 deletions drivers/clk/qcom/clk-rcg2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
93 changes: 93 additions & 0 deletions drivers/clk/qcom/clk-rpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = { \
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -269,6 +288,32 @@ static void clk_rpm_unprepare(struct clk_hw *hw)
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)
{
Expand Down Expand Up @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -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 },
{ }
};
Expand Down
82 changes: 82 additions & 0 deletions drivers/clk/qcom/clk-smd-rpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
17 changes: 17 additions & 0 deletions include/dt-bindings/clock/qcom,rpmcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Loading

0 comments on commit 8f62040

Please sign in to comment.