Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-omap2/clkt2xxx_apll.c
10817 views
1
/*
2
* OMAP2xxx APLL clock control functions
3
*
4
* Copyright (C) 2005-2008 Texas Instruments, Inc.
5
* Copyright (C) 2004-2010 Nokia Corporation
6
*
7
* Contacts:
8
* Richard Woodruff <[email protected]>
9
* Paul Walmsley
10
*
11
* Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
12
* Gordon McNutt and RidgeRun, Inc.
13
*
14
* This program is free software; you can redistribute it and/or modify
15
* it under the terms of the GNU General Public License version 2 as
16
* published by the Free Software Foundation.
17
*/
18
#undef DEBUG
19
20
#include <linux/kernel.h>
21
#include <linux/clk.h>
22
#include <linux/io.h>
23
24
#include <plat/clock.h>
25
#include <plat/prcm.h>
26
27
#include "clock.h"
28
#include "clock2xxx.h"
29
#include "cm2xxx_3xxx.h"
30
#include "cm-regbits-24xx.h"
31
32
/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
33
#define EN_APLL_STOPPED 0
34
#define EN_APLL_LOCKED 3
35
36
/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
37
#define APLLS_CLKIN_19_2MHZ 0
38
#define APLLS_CLKIN_13MHZ 2
39
#define APLLS_CLKIN_12MHZ 3
40
41
void __iomem *cm_idlest_pll;
42
43
/* Private functions */
44
45
/* Enable an APLL if off */
46
static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
47
{
48
u32 cval, apll_mask;
49
50
apll_mask = EN_APLL_LOCKED << clk->enable_bit;
51
52
cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
53
54
if ((cval & apll_mask) == apll_mask)
55
return 0; /* apll already enabled */
56
57
cval &= ~apll_mask;
58
cval |= apll_mask;
59
omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
60
61
omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
62
OMAP24XX_CM_IDLEST_VAL, clk->name);
63
64
/*
65
* REVISIT: Should we return an error code if omap2_wait_clock_ready()
66
* fails?
67
*/
68
return 0;
69
}
70
71
static int omap2_clk_apll96_enable(struct clk *clk)
72
{
73
return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL_MASK);
74
}
75
76
static int omap2_clk_apll54_enable(struct clk *clk)
77
{
78
return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL_MASK);
79
}
80
81
static void _apll96_allow_idle(struct clk *clk)
82
{
83
omap2xxx_cm_set_apll96_auto_low_power_stop();
84
}
85
86
static void _apll96_deny_idle(struct clk *clk)
87
{
88
omap2xxx_cm_set_apll96_disable_autoidle();
89
}
90
91
static void _apll54_allow_idle(struct clk *clk)
92
{
93
omap2xxx_cm_set_apll54_auto_low_power_stop();
94
}
95
96
static void _apll54_deny_idle(struct clk *clk)
97
{
98
omap2xxx_cm_set_apll54_disable_autoidle();
99
}
100
101
/* Stop APLL */
102
static void omap2_clk_apll_disable(struct clk *clk)
103
{
104
u32 cval;
105
106
cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
107
cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
108
omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
109
}
110
111
/* Public data */
112
113
const struct clkops clkops_apll96 = {
114
.enable = omap2_clk_apll96_enable,
115
.disable = omap2_clk_apll_disable,
116
.allow_idle = _apll96_allow_idle,
117
.deny_idle = _apll96_deny_idle,
118
};
119
120
const struct clkops clkops_apll54 = {
121
.enable = omap2_clk_apll54_enable,
122
.disable = omap2_clk_apll_disable,
123
.allow_idle = _apll54_allow_idle,
124
.deny_idle = _apll54_deny_idle,
125
};
126
127
/* Public functions */
128
129
u32 omap2xxx_get_apll_clkin(void)
130
{
131
u32 aplls, srate = 0;
132
133
aplls = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
134
aplls &= OMAP24XX_APLLS_CLKIN_MASK;
135
aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
136
137
if (aplls == APLLS_CLKIN_19_2MHZ)
138
srate = 19200000;
139
else if (aplls == APLLS_CLKIN_13MHZ)
140
srate = 13000000;
141
else if (aplls == APLLS_CLKIN_12MHZ)
142
srate = 12000000;
143
144
return srate;
145
}
146
147
148