blob: 6064a8e193ab784927e30dbfe011efc3485b1e90 [file] [log] [blame]
Amol Jadic2c941c2012-06-22 00:02:01 -07001/*
Duy Truongf3ac7b32013-02-13 01:07:28 -08002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Amol Jadic2c941c2012-06-22 00:02:01 -07003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
Duy Truongf3ac7b32013-02-13 01:07:28 -080011 * * Neither the name of The Linux Foundation nor
Amol Jadic2c941c2012-06-22 00:02:01 -070012 * the names of its contributors may be used to endorse or promote
13 * products derived from this software without specific prior written
14 * permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <stdint.h>
30#include <debug.h>
31#include <reg.h>
32#include <err.h>
33#include <bits.h>
34#include <limits.h>
35#include <platform/timer.h>
36#include <clock.h>
37#include <clock_pll.h>
38
39/*
40 * pll_vote_clk functions
41 */
42int pll_vote_clk_enable(struct clk *clk)
43{
44 uint32_t ena;
45 struct pll_vote_clk *pll = to_pll_vote_clk(clk);
46
47 ena = readl_relaxed(pll->en_reg);
48 ena |= pll->en_mask;
49 writel_relaxed(ena, pll->en_reg);
50
51 /* Wait until PLL is enabled */
52 while ((readl_relaxed(pll->status_reg) & pll->status_mask) == 0);
53
54 return 0;
55}
56
57void pll_vote_clk_disable(struct clk *clk)
58{
59 uint32_t ena;
60 struct pll_vote_clk *pll = to_pll_vote_clk(clk);
61
62 ena = readl_relaxed(pll->en_reg);
63 ena &= ~(pll->en_mask);
64 writel_relaxed(ena, pll->en_reg);
65}
66
67unsigned pll_vote_clk_get_rate(struct clk *clk)
68{
69 struct pll_vote_clk *pll = to_pll_vote_clk(clk);
70 return pll->rate;
71}
72
73struct clk *pll_vote_clk_get_parent(struct clk *clk)
74{
75 struct pll_vote_clk *pll = to_pll_vote_clk(clk);
76 return pll->parent;
77}
78
79int pll_vote_clk_is_enabled(struct clk *clk)
80{
81 struct pll_vote_clk *pll = to_pll_vote_clk(clk);
82 return !!(readl_relaxed(pll->status_reg) & pll->status_mask);
83}
84
85/*
86 * PLLs functions
87 */
88int pll_clk_enable(struct clk *clk)
89{
90 uint32_t mode;
91 struct pll_clk *pll = to_pll_clk(clk);
92
93 mode = readl_relaxed(pll->mode_reg);
94 /* Disable PLL bypass mode. */
95 mode |= BIT(1);
96 writel_relaxed(mode, pll->mode_reg);
97
98 /*
99 * H/W requires a 5us delay between disabling the bypass and
100 * de-asserting the reset. Delay 10us just to be safe.
101 */
102 udelay(10);
103
104 /* De-assert active-low PLL reset. */
105 mode |= BIT(2);
106 writel_relaxed(mode, pll->mode_reg);
107
108 /* Wait until PLL is locked. */
109 udelay(50);
110
111 /* Enable PLL output. */
112 mode |= BIT(0);
113 writel_relaxed(mode, pll->mode_reg);
114
115 return 0;
116}
117
118void pll_clk_disable(struct clk *clk)
119{
120 uint32_t mode;
121 struct pll_clk *pll = to_pll_clk(clk);
122
123 /*
124 * Disable the PLL output, disable test mode, enable
125 * the bypass mode, and assert the reset.
126 */
127 mode = readl_relaxed(pll->mode_reg);
128 mode &= ~BM(3, 0);
129 writel_relaxed(mode, pll->mode_reg);
130}
131
132unsigned pll_clk_get_rate(struct clk *clk)
133{
134 struct pll_clk *pll = to_pll_clk(clk);
135 return pll->rate;
136}
137
138struct clk *pll_clk_get_parent(struct clk *clk)
139{
140 struct pll_clk *pll = to_pll_clk(clk);
141 return pll->parent;
142}
143