2 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <console/console.h>
35 #include <soc/clock.h>
36 #include <soc/lcc-reg.h>
47 typedef struct __packed
{
51 typedef struct __packed
{
61 typedef struct __packed
{
66 } Ipq806xLccAhbixRegs
;
68 typedef struct __packed
{
74 typedef struct __packed
{
87 static const struct lcc_freq_tbl lcc_mi2s_freq_tbl
[] = {
88 { 1024000, 4, 1, 96, 8 },
89 { 1411200, 4, 2, 139, 8 },
90 { 1536000, 4, 1, 64, 8 },
91 { 2048000, 4, 1, 48, 8 },
92 { 2116800, 4, 2, 93, 8 },
93 { 2304000, 4, 2, 85, 8 },
94 { 2822400, 4, 6, 209, 8 },
95 { 3072000, 4, 1, 32, 8 },
96 { 3175200, 4, 1, 31, 8 },
97 { 4096000, 4, 1, 24, 8 },
98 { 4233600, 4, 9, 209, 8 },
99 { 4608000, 4, 3, 64, 8 },
100 { 5644800, 4, 12, 209, 8 },
101 { 6144000, 4, 1, 16, 8 },
102 { 6350400, 4, 2, 31, 8 },
103 { 8192000, 4, 1, 12, 8 },
104 { 8467200, 4, 18, 209, 8 },
105 { 9216000, 4, 3, 32, 8 },
106 { 11289600, 4, 24, 209, 8 },
107 { 12288000, 4, 1, 8, 8 },
108 { 12700800, 4, 27, 209, 8 },
109 { 13824000, 4, 9, 64, 8 },
110 { 16384000, 4, 1, 6, 8 },
111 { 16934400, 4, 41, 238, 8 },
112 { 18432000, 4, 3, 16, 8 },
113 { 22579200, 2, 24, 209, 8 },
114 { 24576000, 4, 1, 4, 8 },
115 { 27648000, 4, 9, 32, 8 },
116 { 33868800, 4, 41, 119, 8 },
117 { 36864000, 4, 3, 8, 8 },
118 { 45158400, 1, 24, 209, 8 },
119 { 49152000, 4, 1, 2, 8 },
120 { 50803200, 1, 27, 209, 8 },
124 static int lcc_init_enable_pll0(Ipq806xLccClocks
*bus
)
126 Ipq806xLccGccRegs
*gcc_regs
= bus
->gcc_apcs_regs
;
127 Ipq806xLccPll0Regs
*pll0_regs
= bus
->lcc_pll0_regs
;
128 Ipq806xLccPllRegs
*pll_regs
= bus
->lcc_pll_regs
;
132 regval
= 15 << LCC_PLL0_L_SHIFT
& LCC_PLL0_L_MASK
;
133 write32(&pll0_regs
->l_val
, regval
);
136 regval
= 145 << LCC_PLL0_M_SHIFT
& LCC_PLL0_M_MASK
;
137 write32(&pll0_regs
->m_val
, regval
);
140 regval
= 199 << LCC_PLL0_N_SHIFT
& LCC_PLL0_N_MASK
;
141 write32(&pll0_regs
->n_val
, regval
);
144 regval
|= LCC_PLL0_CFG_LV_MAIN_ENABLE
;
145 regval
|= LCC_PLL0_CFG_FRAC_ENABLE
;
146 write32(&pll0_regs
->config
, regval
);
149 regval
|= LCC_PLL_PCLK_SRC_PRI
;
150 write32(&pll_regs
->pri
, regval
);
153 regval
|= 1 << LCC_PLL0_MODE_BIAS_CNT_SHIFT
&
154 LCC_PLL0_MODE_BIAS_CNT_MASK
;
155 regval
|= 8 << LCC_PLL0_MODE_LOCK_CNT_SHIFT
&
156 LCC_PLL0_MODE_LOCK_CNT_MASK
;
157 write32(&pll0_regs
->mode
, regval
);
159 regval
= read32(&gcc_regs
->apcs
);
160 regval
|= GCC_PLL_APCS_PLL4_ENABLE
;
161 write32(&gcc_regs
->apcs
, regval
);
163 regval
= read32(&pll0_regs
->mode
);
164 regval
|= LCC_PLL0_MODE_FSM_VOTE_ENABLE
;
165 write32(&pll0_regs
->mode
, regval
);
169 regval
= read32(&pll0_regs
->status
);
170 if (regval
& LCC_PLL0_STAT_ACTIVE_MASK
)
173 printk(BIOS_ERR
, "%s: error enabling PLL4 clock\n", __func__
);
177 static int lcc_init_enable_ahbix(Ipq806xLccClocks
*bus
)
179 Ipq806xLccAhbixRegs
*ahbix_regs
= bus
->lcc_ahbix_regs
;
183 regval
|= 1 << LCC_AHBIX_MD_M_VAL_SHIFT
& LCC_AHBIX_MD_M_VAL_MASK
;
184 regval
|= 252 << LCC_AHBIX_MD_NOT_2D_VAL_SHIFT
&
185 LCC_AHBIX_MD_NOT_2D_VAL_MASK
;
186 write32(&ahbix_regs
->md
, regval
);
189 regval
|= 253 << LCC_AHBIX_NS_N_VAL_SHIFT
& LCC_AHBIX_NS_N_VAL_MASK
;
190 regval
|= LCC_AHBIX_NS_CRC_ENABLE
;
191 regval
|= LCC_AHBIX_NS_GFM_SEL_MNC
;
192 regval
|= LCC_AHBIX_NS_MNC_CLK_ENABLE
;
193 regval
|= LCC_AHBIX_NS_MNC_ENABLE
;
194 regval
|= LCC_AHBIX_NS_MNC_MODE_DUAL
;
195 regval
|= LCC_AHBIX_NS_PREDIV_BYPASS
;
196 regval
|= LCC_AHBIX_NS_MN_SRC_LPA
;
197 write32(&ahbix_regs
->ns
, regval
);
201 regval
= read32(&ahbix_regs
->status
);
202 if (regval
& LCC_AHBIX_STAT_AIF_CLK_MASK
)
205 printk(BIOS_ERR
, "%s: error enabling AHBIX clock\n", __func__
);
209 static int lcc_init_mi2s(Ipq806xLccClocks
*bus
, unsigned freq
)
211 Ipq806xLccMi2sRegs
*mi2s_regs
= bus
->lcc_mi2s_regs
;
217 while (lcc_mi2s_freq_tbl
[i
].freq
!= 0) {
218 if (lcc_mi2s_freq_tbl
[i
].freq
== freq
)
222 if (lcc_mi2s_freq_tbl
[i
].freq
== 0) {
223 printk(BIOS_ERR
, "%s: invalid frequency given: %u\n",
228 switch (lcc_mi2s_freq_tbl
[i
].pd
) {
230 pd
= LCC_MI2S_NS_PREDIV_BYPASS
;
233 pd
= LCC_MI2S_NS_PREDIV_DIV2
;
236 pd
= LCC_MI2S_NS_PREDIV_DIV4
;
239 printk(BIOS_ERR
, "%s: invalid prediv found: %u\n", __func__
,
240 lcc_mi2s_freq_tbl
[i
].pd
);
244 m
= lcc_mi2s_freq_tbl
[i
].m
;
245 n
= ~(lcc_mi2s_freq_tbl
[i
].n
- m
);
246 d
= ~(lcc_mi2s_freq_tbl
[i
].d
* 2);
249 regval
|= m
<< LCC_MI2S_MD_M_VAL_SHIFT
& LCC_MI2S_MD_M_VAL_MASK
;
250 regval
|= d
<< LCC_MI2S_MD_NOT_2D_VAL_SHIFT
&
251 LCC_MI2S_MD_NOT_2D_VAL_MASK
;
252 write32(&mi2s_regs
->md
, regval
);
255 regval
|= n
<< LCC_MI2S_NS_N_VAL_SHIFT
& LCC_MI2S_NS_N_VAL_MASK
;
256 regval
|= LCC_MI2S_NS_BIT_DIV_DIV4
;
257 regval
|= LCC_MI2S_NS_MNC_CLK_ENABLE
;
258 regval
|= LCC_MI2S_NS_MNC_ENABLE
;
259 regval
|= LCC_MI2S_NS_MNC_MODE_DUAL
;
261 regval
|= LCC_MI2S_NS_MN_SRC_LPA
;
262 write32(&mi2s_regs
->ns
, regval
);
267 static int lcc_enable_mi2s(Ipq806xLccClocks
*bus
)
269 Ipq806xLccMi2sRegs
*mi2s_regs
= bus
->lcc_mi2s_regs
;
272 regval
= read32(&mi2s_regs
->ns
);
273 regval
|= LCC_MI2S_NS_OSR_CXC_ENABLE
;
274 regval
|= LCC_MI2S_NS_BIT_CXC_ENABLE
;
275 write32(&mi2s_regs
->ns
, regval
);
279 regval
= read32(&mi2s_regs
->status
);
280 if (regval
& LCC_MI2S_STAT_OSR_CLK_MASK
)
281 if (regval
& LCC_MI2S_STAT_BIT_CLK_MASK
)
284 printk(BIOS_ERR
, "%s: error enabling MI2S clocks: %u\n",
289 int audio_clock_config(unsigned frequency
)
291 Ipq806xLccClocks
*bus
= malloc(sizeof(*bus
));
294 printk(BIOS_ERR
, "%s: failed to allocate bus structure\n",
299 bus
->gcc_apcs_regs
= (void *)(MSM_GCC_BASE
+ GCC_PLL_APCS_REG
);
300 bus
->lcc_pll0_regs
= (void *)(MSM_LPASS_LCC_BASE
+ LCC_PLL0_MODE_REG
);
301 bus
->lcc_ahbix_regs
= (void *)(MSM_LPASS_LCC_BASE
+ LCC_AHBIX_NS_REG
);
302 bus
->lcc_mi2s_regs
= (void *)(MSM_LPASS_LCC_BASE
+ LCC_MI2S_NS_REG
);
303 bus
->lcc_pll_regs
= (void *)(MSM_LPASS_LCC_BASE
+ LCC_PLL_PCLK_REG
);
306 if (lcc_init_enable_pll0(bus
))
308 if (lcc_init_enable_ahbix(bus
))
310 if (lcc_init_mi2s(bus
, frequency
))
313 if (lcc_enable_mi2s(bus
))