Allwinner clock changes for 7.3

Some cleanups to the Allwinner clock driver library and support for the
 Allwinner A733 RTC clocks added.
 -----BEGIN PGP SIGNATURE-----
 
 iQJEBAABCgAuFiEE2nN1m/hhnkhOWjtHOJpUIZwPJDAFAmp4YtEQHHdlbnNAa2Vy
 bmVsLm9yZwAKCRA4mlQhnA8kMOIFEADkvYPkegyGZWpVRlRuvV1mzE0Uc16Ueo4G
 jisA5FSjOOjR1v8JcG16gvX0uvllWBTyHRQUJ/4VRexedRcL/QQewID7kZ4Ebh+M
 BGuSbEHiPUqLTDO0j9mNE5Cu6fmIvrMSCyffxFqCbmhfvb5XiCIPeNtA9Q9V18dK
 UMSIh9NUU2JKINnJJnBpL/3akPxUDUEBRx2MfuW85hb/0irsWaYAGEToFLNBYBhf
 r5QUcXnrMgV7mvFPLHjG0TytPWRDTiNR/aXlXtPuLPx7TgTuKMSwt2b7mGv7+kz0
 rPooPw48TfpFVoGmBx22FmD4BJuHyi8BUTQfWluSpw+MZpwmURYDhfQiyPjPASAC
 nSDWIFL5s0i/R2Gtql+sbqpY3zDADxta/jRsUG/0azEALjcVNNuWWr9f/h0QxiDB
 MRLrUFKRx6TwQBSgyMRkk43wA0pWKn9koZaB1FFu3if03heRk/Qt/YOcg7mp0xP7
 EW0PZfKq3GXBWtcQ0UlC6jOzF+X0MFWlNCOSxkNR460H+K2jQdMaU+rUx0N1qXnA
 qN9uoMzukXd9x6GazWDA4tOfbc6fYSQ8R40EQNLsrjCaYq6gf/ED1V83D60/2TnM
 8rpxDagwTLndtT+oO2DkCEk60XVpnRodkyzLXlQ+wHNF0FjddDA/I29QLAcN5bvl
 kjsWWCFtTw==
 =1HWO
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCAAyFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmp8DggUHHN3Ym95ZEBj
 aHJvbWl1bS5vcmcACgkQrQKIl8bklSXnBQ//fyZ0fFm5sAO5Dl4/d52hbv4i4SLa
 Wv/R+dEbrHrMlU5Vd1WSHImf0XqG97MZNlGlNor3fcM98Z9bQo3NZFOGTUkjJs6W
 yJGs/68mJpZvfqYHBXBk+PlYBDD7ULNOAgz8TSsrjuLS0ehpvmI40eYhcczqZLqe
 wupz/upveK81a9qDQfpfrIF7pb5Xf57YTQnkFRJkrL7Jyhu6+jSp0YhnqXpTOz+w
 RtPqHGSl+kquLPGgmzZmDS2lUZfRr/MrEbP2LsEhoqK2rBLQGnoYYtxlBBDKgtdc
 VEjpsp3dk8TnckgAZZF+Az13PoOYIXXP6EoSez+V5UANGCXjxB+Xh1JNdGmsYF5+
 awI6fjlND8xKsGGz5tKMvZXuqf1a+cF8sqqI0cJ6roLN7DUQEc2lSPN5Ao6eaw+A
 ljV7hUe/7RyIS1rvJtMVy60g6+9hqGPtQqqM8xV+2brCguL/sj6aW16P9ZEy+wvv
 LLJev2Ojt0I2JCwyYkDqCX8EefNfZGFAVe3+fUUunNHahQjXlCv1IWe6vqbI78dR
 uTWP9n3ohTozg4PNDSxjOZxQaueGL6ZTfBwLTrXk6tVo4Q4pawMH0q+VIvr3Hzc7
 ifOK5/NN6oq/dAfXIukRFBXdGSGRyMNt7sYfq9r2CxGP/9NqeF4g9H2Uxotu0q5C
 YyLtNcH2+pTsUUE=
 =3i3v
 -----END PGP SIGNATURE-----

Merge tag 'sunxi-clk-for-7.3' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-allwinner

Pull Allwinner clk driver updates from Chen-Yu Tsai:

Some cleanups to the Allwinner clock driver library and support for the
Allwinner A733 RTC clocks added.

* tag 'sunxi-clk-for-7.3' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux:
  clk: sunxi-ng: sun6i-rtc: add a733 support
  clk: sunxi-ng: sun6i-rtc: split main oscillator div and gate
  clk: sunxi-ng: div: add read-only operation support
  clk: sunxi-ng: mux: fix determine helper rate propagation
  clk: sunxi-ng: mux: remove unneeded export
  clk: sunxi-ng: sun6i-rtc: Add feature bit for IOSC calibration
  clk: sunxi-ng: sun6i-rtc: clean up DT usage
  clk: sunxi-ng: fix ccu probe clock unregister on error
  dt-bindings: rtc: sun6i: add sun60i-a733 support
  dt-bindings: rtc: sun6i: no clock-output-names on h616/r329
This commit is contained in:
Stephen Boyd 2026-08-11 23:08:57 -07:00
commit d8a8d206a7
9 changed files with 176 additions and 74 deletions

View File

@ -33,6 +33,7 @@ properties:
- enum:
- allwinner,sun20i-d1-rtc
- allwinner,sun55i-a523-rtc
- allwinner,sun60i-a733-rtc
- const: allwinner,sun50i-r329-rtc
reg:
@ -175,6 +176,18 @@ allOf:
interrupts:
minItems: 2
- if:
properties:
compatible:
contains:
enum:
- allwinner,sun50i-h616-rtc
- allwinner,sun50i-r329-rtc
then:
properties:
clock-output-names: false
required:
- "#clock-cells"
- compatible

View File

@ -44,16 +44,20 @@
#define DCXO_CTRL_REG 0x160
#define DCXO_CTRL_CLK16M_RC_EN BIT(0)
#define DCXO_GATING_REG 0x16c
#define CLK_NUMBER_NO_GATES (CLK_OSC24M_32K_DIV + 1)
struct sun6i_rtc_match_data {
bool have_ext_osc32k : 1;
bool have_iosc_calibration : 1;
bool have_dcxo_status : 1;
bool have_phy_ref_gates : 1;
bool rtc_32k_single_parent : 1;
const struct clk_parent_data *osc32k_fanout_parents;
u8 osc32k_fanout_nparents;
};
static bool have_iosc_calibration;
static int ccu_iosc_enable(struct clk_hw *hw)
{
struct ccu_common *cm = hw_to_ccu_common(hw);
@ -80,7 +84,7 @@ static unsigned long ccu_iosc_recalc_rate(struct clk_hw *hw,
{
struct ccu_common *cm = hw_to_ccu_common(hw);
if (have_iosc_calibration) {
if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
u32 reg = readl(cm->base + IOSC_CLK_CALI_REG);
/*
@ -119,7 +123,7 @@ static int ccu_iosc_32k_prepare(struct clk_hw *hw)
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val;
if (!have_iosc_calibration)
if (!(cm->features & CCU_FEATURE_IOSC_CALIBRATION))
return 0;
val = readl(cm->base + IOSC_CLK_CALI_REG);
@ -134,7 +138,7 @@ static void ccu_iosc_32k_unprepare(struct clk_hw *hw)
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val;
if (!have_iosc_calibration)
if (!(cm->features & CCU_FEATURE_IOSC_CALIBRATION))
return;
val = readl(cm->base + IOSC_CLK_CALI_REG);
@ -148,7 +152,7 @@ static unsigned long ccu_iosc_32k_recalc_rate(struct clk_hw *hw,
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val;
if (have_iosc_calibration) {
if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
val = readl(cm->base + IOSC_CLK_CALI_REG);
/* Assume the calibrated 32k clock is accurate. */
@ -167,7 +171,7 @@ static unsigned long ccu_iosc_32k_recalc_accuracy(struct clk_hw *hw,
struct ccu_common *cm = hw_to_ccu_common(hw);
u32 val;
if (have_iosc_calibration) {
if (cm->features & CCU_FEATURE_IOSC_CALIBRATION) {
val = readl(cm->base + IOSC_CLK_CALI_REG);
/* Assume the calibrated 32k clock is accurate. */
@ -191,10 +195,8 @@ static struct ccu_common iosc_32k_clk = {
CLK_GET_RATE_NOCACHE),
};
static const struct clk_hw *ext_osc32k[] = { NULL }; /* updated during probe */
static SUNXI_CCU_GATE_HWS(ext_osc32k_gate_clk, "ext-osc32k-gate",
ext_osc32k, 0x0, BIT(4), 0);
static SUNXI_CCU_GATE_FW(ext_osc32k_gate_clk, "ext-osc32k-gate",
"ext-osc32k", 0x0, BIT(4), 0);
static const struct clk_hw *osc32k_parents[] = {
&iosc_32k_clk.hw,
@ -217,22 +219,50 @@ static struct ccu_mux osc32k_clk = {
},
};
/* This falls back to the global name for fwnodes without a named reference. */
/*
* This falls back to the global name for fwnodes without a named reference.
* NOTE: osc24M name might be misleading the oscillator could also be a 26MHz
* or a 19.2MHz one starting with the a733. The original name is kept anyway
* in case anything is relying on it.
*/
static const struct clk_parent_data osc24M[] = {
{ .fw_name = "hosc", .name = "osc24M" }
};
static struct ccu_gate osc24M_32k_clk = {
.enable = BIT(16),
static struct clk_fixed_factor osc24M_32k_div_clk = {
.mult = 1,
.div = 750,
.hw.init = CLK_HW_INIT_PARENTS_DATA("osc24M-32k-div",
osc24M,
&clk_fixed_factor_ops,
0),
};
static struct clk_div_table osc24M_32k_div_a733_table[] = {
{ .val = 0, .div = 732 },
{ .val = 1, .div = 586 },
{ .val = 2, .div = 793 },
{ .val = 3, .div = 732 },
{ /* Sentinel */ },
};
static struct ccu_div osc24M_32k_div_a733_clk = {
.enable = BIT(1),
.div = _SUNXI_CCU_DIV_TABLE_FLAGS(14, 2,
osc24M_32k_div_a733_table,
CLK_DIVIDER_READ_ONLY),
.common = {
.reg = LOSC_OUT_GATING_REG,
.prediv = 750,
.features = CCU_FEATURE_ALL_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS_DATA("osc24M-32k", osc24M,
&ccu_gate_ops, 0),
.reg = DCXO_CTRL_REG,
.hw.init = CLK_HW_INIT_PARENTS_DATA("osc24M-32k-div",
osc24M,
&ccu_rodiv_ops,
0),
},
};
static SUNXI_CCU_GATE(osc24M_32k_clk, "osc24M-32k", "osc24M-32k-div",
LOSC_OUT_GATING_REG, BIT(16), 0);
static const struct clk_hw *rtc_32k_parents[] = {
&osc32k_clk.common.hw,
&osc24M_32k_clk.common.hw
@ -270,6 +300,15 @@ static struct ccu_mux osc32k_fanout_clk = {
},
};
static SUNXI_CCU_GATE_FW(hosc_serdes1_clk, "hosc-serdes1", "hosc",
DCXO_GATING_REG, BIT(5), 0);
static SUNXI_CCU_GATE_FW(hosc_serdes0_clk, "hosc-serdes0", "hosc",
DCXO_GATING_REG, BIT(4), 0);
static SUNXI_CCU_GATE_FW(hosc_hdmi_clk, "hosc-hdmi", "hosc",
DCXO_GATING_REG, BIT(1), 0);
static SUNXI_CCU_GATE_FW(hosc_ufs_clk, "hosc-ufs", "hosc",
DCXO_GATING_REG, BIT(0), 0);
static struct ccu_common *sun6i_rtc_ccu_clks[] = {
&iosc_clk,
&iosc_32k_clk,
@ -278,6 +317,11 @@ static struct ccu_common *sun6i_rtc_ccu_clks[] = {
&osc24M_32k_clk.common,
&rtc_32k_clk.common,
&osc32k_fanout_clk.common,
&osc24M_32k_div_a733_clk.common,
&hosc_serdes1_clk.common,
&hosc_serdes0_clk.common,
&hosc_hdmi_clk.common,
&hosc_ufs_clk.common,
};
static struct clk_hw_onecell_data sun6i_rtc_ccu_hw_clks = {
@ -290,6 +334,11 @@ static struct clk_hw_onecell_data sun6i_rtc_ccu_hw_clks = {
[CLK_EXT_OSC32K_GATE] = &ext_osc32k_gate_clk.common.hw,
[CLK_OSC24M_32K] = &osc24M_32k_clk.common.hw,
[CLK_RTC_32K] = &rtc_32k_clk.common.hw,
[CLK_OSC24M_32K_DIV] = &osc24M_32k_div_clk.hw,
[CLK_HOSC_UFS] = &hosc_ufs_clk.common.hw,
[CLK_HOSC_HDMI] = &hosc_hdmi_clk.common.hw,
[CLK_HOSC_SERDES0] = &hosc_serdes0_clk.common.hw,
[CLK_HOSC_SERDES1] = &hosc_serdes1_clk.common.hw,
},
};
@ -332,6 +381,15 @@ static const struct sun6i_rtc_match_data sun55i_a523_rtc_ccu_data = {
.osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents),
};
static const struct sun6i_rtc_match_data sun60i_a733_rtc_ccu_data = {
.have_ext_osc32k = true,
.have_iosc_calibration = true,
.have_dcxo_status = true,
.have_phy_ref_gates = true,
.osc32k_fanout_parents = sun50i_r329_osc32k_fanout_parents,
.osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents),
};
static const struct of_device_id sun6i_rtc_ccu_match[] = {
{
.compatible = "allwinner,sun50i-h616-rtc",
@ -345,6 +403,10 @@ static const struct of_device_id sun6i_rtc_ccu_match[] = {
.compatible = "allwinner,sun55i-a523-rtc",
.data = &sun55i_a523_rtc_ccu_data,
},
{
.compatible = "allwinner,sun60i-a733-rtc",
.data = &sun60i_a733_rtc_ccu_data,
},
{},
};
MODULE_DEVICE_TABLE(of, sun6i_rtc_ccu_match);
@ -352,7 +414,6 @@ MODULE_DEVICE_TABLE(of, sun6i_rtc_ccu_match);
int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
{
const struct sun6i_rtc_match_data *data;
struct clk *ext_osc32k_clk = NULL;
const struct of_device_id *match;
/* This driver is only used for newer variants of the hardware. */
@ -361,23 +422,12 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
return 0;
data = match->data;
have_iosc_calibration = data->have_iosc_calibration;
if (data->have_ext_osc32k) {
const char *fw_name;
/* ext-osc32k was the only input clock in the old binding. */
fw_name = of_property_present(dev->of_node, "clock-names")
? "ext-osc32k" : NULL;
ext_osc32k_clk = devm_clk_get_optional(dev, fw_name);
if (IS_ERR(ext_osc32k_clk))
return PTR_ERR(ext_osc32k_clk);
if (data->have_iosc_calibration) {
iosc_clk.features |= CCU_FEATURE_IOSC_CALIBRATION;
iosc_32k_clk.features |= CCU_FEATURE_IOSC_CALIBRATION;
}
if (ext_osc32k_clk) {
/* Link ext-osc32k-gate to its parent. */
*ext_osc32k = __clk_get_hw(ext_osc32k_clk);
} else {
if (!data->have_ext_osc32k) {
/* ext-osc32k-gate is an orphan, so do not register it. */
sun6i_rtc_ccu_hw_clks.hws[CLK_EXT_OSC32K_GATE] = NULL;
osc32k_init_data.num_parents = 1;
@ -389,6 +439,13 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
osc32k_fanout_init_data.parent_data = data->osc32k_fanout_parents;
osc32k_fanout_init_data.num_parents = data->osc32k_fanout_nparents;
if (data->have_dcxo_status)
sun6i_rtc_ccu_hw_clks.hws[CLK_OSC24M_32K_DIV] =
&osc24M_32k_div_a733_clk.common.hw;
if (!data->have_phy_ref_gates)
sun6i_rtc_ccu_hw_clks.num = CLK_NUMBER_NO_GATES;
return devm_sunxi_ccu_probe(dev, reg, &sun6i_rtc_ccu_desc);
}

View File

@ -9,7 +9,8 @@
#define CLK_EXT_OSC32K_GATE 4
#define CLK_OSC24M_32K 5
#define CLK_RTC_32K 6
#define CLK_OSC24M_32K_DIV 7
#define CLK_NUMBER (CLK_RTC_32K + 1)
#define CLK_NUMBER (CLK_HOSC_SERDES1 + 1)
#endif /* _CCU_SUN6I_RTC_H */

View File

@ -114,7 +114,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
const struct sunxi_ccu_desc *desc)
{
struct ccu_reset *reset;
int i, ret;
int i, j, ret;
ccu->desc = desc;
@ -130,8 +130,8 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
cclk->lock = &ccu->lock;
}
for (i = 0; i < desc->hw_clks->num ; i++) {
struct clk_hw *hw = desc->hw_clks->hws[i];
for (j = 0; j < desc->hw_clks->num ; j++) {
struct clk_hw *hw = desc->hw_clks->hws[j];
const char *name;
if (!hw)
@ -143,7 +143,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
else
ret = of_clk_hw_register(node, hw);
if (ret) {
pr_err("Couldn't register clock %d - %s\n", i, name);
pr_err("Couldn't register clock %d - %s\n", j, name);
goto err_clk_unreg;
}
}
@ -186,8 +186,8 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
err_del_provider:
of_clk_del_provider(node);
err_clk_unreg:
while (--i >= 0) {
struct clk_hw *hw = desc->hw_clks->hws[i];
while (--j >= 0) {
struct clk_hw *hw = desc->hw_clks->hws[j];
if (!hw)
continue;

View File

@ -21,6 +21,7 @@
#define CCU_FEATURE_CLOSEST_RATE BIT(9)
#define CCU_FEATURE_DUAL_DIV BIT(10)
#define CCU_FEATURE_UPDATE_BIT BIT(11)
#define CCU_FEATURE_IOSC_CALIBRATION BIT(12)
/* MMC timing mode switch bit */
#define CCU_MMC_NEW_TIMING_MODE BIT(30)

View File

@ -20,8 +20,22 @@ static int ccu_div_determine_rate_helper(struct ccu_mux_internal *mux,
if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
req->rate *= cd->fixed_post_div;
ret = divider_determine_rate(&cd->common.hw, req, cd->div.table,
cd->div.width, cd->div.flags);
if (cd->div.flags & CLK_DIVIDER_READ_ONLY) {
unsigned long val;
u32 reg;
reg = readl(cd->common.base + cd->common.reg);
val = reg >> cd->div.shift;
val &= (1 << cd->div.width) - 1;
ret = divider_ro_determine_rate(&cd->common.hw, req, cd->div.table,
cd->div.width, cd->div.flags, val);
} else {
ret = divider_determine_rate(&cd->common.hw, req, cd->div.table,
cd->div.width, cd->div.flags);
}
if (ret)
return ret;
@ -143,3 +157,16 @@ const struct clk_ops ccu_div_ops = {
.set_rate = ccu_div_set_rate,
};
EXPORT_SYMBOL_NS_GPL(ccu_div_ops, "SUNXI_CCU");
const struct clk_ops ccu_rodiv_ops = {
.disable = ccu_div_disable,
.enable = ccu_div_enable,
.is_enabled = ccu_div_is_enabled,
.get_parent = ccu_div_get_parent,
.set_parent = ccu_div_set_parent,
.determine_rate = ccu_div_determine_rate,
.recalc_rate = ccu_div_recalc_rate,
};
EXPORT_SYMBOL_NS_GPL(ccu_rodiv_ops, "SUNXI_CCU");

View File

@ -300,5 +300,6 @@ static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
}
extern const struct clk_ops ccu_div_ops;
extern const struct clk_ops ccu_rodiv_ops;
#endif /* _CCU_DIV_H_ */

View File

@ -66,7 +66,6 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
{
return parent_rate / ccu_mux_get_prediv(common, cm, parent_index);
}
EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_apply_prediv, "SUNXI_CCU");
static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common,
struct ccu_mux_internal *cm,
@ -93,66 +92,65 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common,
struct clk_rate_request adj_req = *req;
best_parent = clk_hw_get_parent(hw);
best_parent_rate = clk_hw_get_rate(best_parent);
adj_req.best_parent_rate = clk_hw_get_rate(best_parent);
adj_req.best_parent_hw = best_parent;
adj_req.best_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1,
best_parent_rate);
/*
* This effectively treats the predivider as a postdivider.
* It stays mathematically correct and ensures whatever
* round() will do stays correct while walking the tree.
* It may query the parent rate too while handling rate
* propagation.
*/
adj_req.rate = ccu_mux_helper_unapply_prediv(common, cm, -1,
req->rate);
ret = round(cm, &adj_req, data);
if (ret)
return ret;
best_rate = adj_req.rate;
/*
* best_parent_rate might have been modified by our clock.
* Unapply the pre-divider if there's one, and give
* the actual frequency the parent needs to run at.
* parent_rate might have been modified by our clock as part
* of the rate propagation mechanism. Same goes below.
*/
best_parent_rate = ccu_mux_helper_unapply_prediv(common, cm, -1,
adj_req.best_parent_rate);
best_parent_rate = adj_req.best_parent_rate;
best_rate = ccu_mux_helper_apply_prediv(common, cm, -1,
adj_req.rate);
goto out;
}
for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
struct clk_rate_request tmp_req = *req;
unsigned long parent_rate;
unsigned long rate;
struct clk_hw *parent;
parent = clk_hw_get_parent_by_index(hw, i);
if (!parent)
continue;
parent_rate = ccu_mux_helper_apply_prediv(common, cm, i,
clk_hw_get_rate(parent));
tmp_req.best_parent_hw = parent;
tmp_req.best_parent_rate = parent_rate;
tmp_req.best_parent_rate = clk_hw_get_rate(parent);
tmp_req.rate = ccu_mux_helper_unapply_prediv(common, cm, i,
req->rate);
ret = round(cm, &tmp_req, data);
if (ret)
continue;
/*
* parent_rate might have been modified by our clock.
* Unapply the pre-divider if there's one, and give
* the actual frequency the parent needs to run at.
*/
parent_rate = ccu_mux_helper_unapply_prediv(common, cm, i,
tmp_req.best_parent_rate);
rate = ccu_mux_helper_apply_prediv(common, cm, i,
tmp_req.rate);
if (tmp_req.rate == req->rate) {
if (rate == req->rate) {
best_parent = parent;
best_parent_rate = parent_rate;
best_rate = tmp_req.rate;
best_parent_rate = tmp_req.best_parent_rate;
best_rate = rate;
goto out;
}
if (ccu_is_better_rate(common, req->rate, tmp_req.rate, best_rate)) {
best_rate = tmp_req.rate;
best_parent_rate = parent_rate;
if (ccu_is_better_rate(common, req->rate, rate, best_rate)) {
best_rate = rate;
best_parent_rate = tmp_req.best_parent_rate;
best_parent = parent;
}
}

View File

@ -6,5 +6,9 @@
#define CLK_OSC32K 0
#define CLK_OSC32K_FANOUT 1
#define CLK_IOSC 2
#define CLK_HOSC_UFS 8
#define CLK_HOSC_HDMI 9
#define CLK_HOSC_SERDES0 10
#define CLK_HOSC_SERDES1 11
#endif /* _DT_BINDINGS_CLK_SUN6I_RTC_H_ */