aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/sunxi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-07 23:27:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-07 23:27:30 -0400
commit1a5700bc2d10cd379a795fd2bb377a190af5acd4 (patch)
treee9f754cbc34020dd23c1d2e3e45fb6890ba7593c /drivers/clk/sunxi
parenta68a7509d3af8ee458d32b2416b0c2aaf2a4a7e3 (diff)
parent3cbcb16095f916f50a5a55066fcc4be06946ce1e (diff)
Merge tag 'clk-for-linus-3.16' of git://git.linaro.org/people/mike.turquette/linux into next
Pull clock framework updates from Mike Turquette: "The clock framework changes for 3.16 are pretty typical: mostly clock driver additions and fixes. There are additions to the clock core code for some of the basic types (e.g. the common divider type has some fixes and featured added to it). One minor annoyance is a last-minute dependency that wasn't handled quite right. Commit ba0fae3b06a6 ("clk: berlin: add core clock driver for BG2/BG2CD") in this pull request depends on include/dt-bindings/clock/berlin2.h, which is already in your tree via the arm-soc pull request. Building for the berlin platform will break when the clk tree is built on it's own, but merged into your master branch everything should be fine" * tag 'clk-for-linus-3.16' of git://git.linaro.org/people/mike.turquette/linux: (75 commits) mmc: sunxi: Add driver for SD/MMC hosts found on Allwinner sunxi SoCs clk: export __clk_round_rate for providers clk: versatile: free icst on error return clk: qcom: Return error pointers for unimplemented clocks clk: qcom: Support msm8974pro global clock control hardware clk: qcom: Properly support display clocks on msm8974 clk: qcom: Support display RCG clocks clk: qcom: Return highest rate when round_rate() exceeds plan clk: qcom: Fix mmcc-8974's PLL configurations clk: qcom: Fix clk_rcg2_is_enabled() check clk: berlin: add core clock driver for BG2Q clk: berlin: add core clock driver for BG2/BG2CD clk: berlin: add driver for BG2x complex divider cells clk: berlin: add driver for BG2x simple PLLs clk: berlin: add driver for BG2x audio/video PLL clk: st: Terminate of match table clk/exynos4: Fix compilation warning ARM: shmobile: r8a7779: Add clock index macros for DT sources clk: divider: Fix overflow in clk_divider_bestdiv clk: u300: Terminate of match table ...
Diffstat (limited to 'drivers/clk/sunxi')
-rw-r--r--drivers/clk/sunxi/clk-factors.c36
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c37
2 files changed, 73 insertions, 0 deletions
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index 9e232644f07e..3806d97e529b 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -77,6 +77,41 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
77 return rate; 77 return rate;
78} 78}
79 79
80static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
81 unsigned long *best_parent_rate,
82 struct clk **best_parent_p)
83{
84 struct clk *clk = hw->clk, *parent, *best_parent = NULL;
85 int i, num_parents;
86 unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0;
87
88 /* find the parent that can help provide the fastest rate <= rate */
89 num_parents = __clk_get_num_parents(clk);
90 for (i = 0; i < num_parents; i++) {
91 parent = clk_get_parent_by_index(clk, i);
92 if (!parent)
93 continue;
94 if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT)
95 parent_rate = __clk_round_rate(parent, rate);
96 else
97 parent_rate = __clk_get_rate(parent);
98
99 child_rate = clk_factors_round_rate(hw, rate, &parent_rate);
100
101 if (child_rate <= rate && child_rate > best_child_rate) {
102 best_parent = parent;
103 best = parent_rate;
104 best_child_rate = child_rate;
105 }
106 }
107
108 if (best_parent)
109 *best_parent_p = best_parent;
110 *best_parent_rate = best;
111
112 return best_child_rate;
113}
114
80static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, 115static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
81 unsigned long parent_rate) 116 unsigned long parent_rate)
82{ 117{
@@ -113,6 +148,7 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
113} 148}
114 149
115const struct clk_ops clk_factors_ops = { 150const struct clk_ops clk_factors_ops = {
151 .determine_rate = clk_factors_determine_rate,
116 .recalc_rate = clk_factors_recalc_rate, 152 .recalc_rate = clk_factors_recalc_rate,
117 .round_rate = clk_factors_round_rate, 153 .round_rate = clk_factors_round_rate,
118 .set_rate = clk_factors_set_rate, 154 .set_rate = clk_factors_set_rate,
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 9eddf22d56a4..426483422d3d 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -507,6 +507,43 @@ CLK_OF_DECLARE(sun7i_a20_gmac, "allwinner,sun7i-a20-gmac-clk",
507 507
508 508
509/** 509/**
510 * clk_sunxi_mmc_phase_control() - configures MMC clock phase control
511 */
512
513void clk_sunxi_mmc_phase_control(struct clk *clk, u8 sample, u8 output)
514{
515 #define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
516 #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
517
518 struct clk_hw *hw = __clk_get_hw(clk);
519 struct clk_composite *composite = to_clk_composite(hw);
520 struct clk_hw *rate_hw = composite->rate_hw;
521 struct clk_factors *factors = to_clk_factors(rate_hw);
522 unsigned long flags = 0;
523 u32 reg;
524
525 if (factors->lock)
526 spin_lock_irqsave(factors->lock, flags);
527
528 reg = readl(factors->reg);
529
530 /* set sample clock phase control */
531 reg &= ~(0x7 << 20);
532 reg |= ((sample & 0x7) << 20);
533
534 /* set output clock phase control */
535 reg &= ~(0x7 << 8);
536 reg |= ((output & 0x7) << 8);
537
538 writel(reg, factors->reg);
539
540 if (factors->lock)
541 spin_unlock_irqrestore(factors->lock, flags);
542}
543EXPORT_SYMBOL(clk_sunxi_mmc_phase_control);
544
545
546/**
510 * sunxi_factors_clk_setup() - Setup function for factor clocks 547 * sunxi_factors_clk_setup() - Setup function for factor clocks
511 */ 548 */
512 549