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.
32 #include <console/console.h>
33 #include <soc/clock.h>
34 #include <soc/lcc-reg.h>
35 #include <device/mmio.h>
45 typedef struct __packed
{
49 typedef struct __packed
{
59 typedef struct __packed
{
66 typedef struct __packed
{
72 typedef struct __packed
{
85 static const struct lcc_freq_tbl lcc_mi2s_freq_tbl
[] = {
86 { 1024000, 4, 1, 96, 8 },
87 { 1411200, 4, 2, 139, 8 },
88 { 1536000, 4, 1, 64, 8 },
89 { 2048000, 4, 1, 48, 8 },
90 { 2116800, 4, 2, 93, 8 },
91 { 2304000, 4, 2, 85, 8 },
92 { 2822400, 4, 6, 209, 8 },
93 { 3072000, 4, 1, 32, 8 },
94 { 3175200, 4, 1, 31, 8 },
95 { 4096000, 4, 1, 24, 8 },
96 { 4233600, 4, 9, 209, 8 },
97 { 4608000, 4, 3, 64, 8 },
98 { 5644800, 4, 12, 209, 8 },
99 { 6144000, 4, 1, 16, 8 },
100 { 6350400, 4, 2, 31, 8 },
101 { 8192000, 4, 1, 12, 8 },
102 { 8467200, 4, 18, 209, 8 },
103 { 9216000, 4, 3, 32, 8 },
104 { 11289600, 4, 24, 209, 8 },
105 { 12288000, 4, 1, 8, 8 },
106 { 12700800, 4, 27, 209, 8 },
107 { 13824000, 4, 9, 64, 8 },
108 { 16384000, 4, 1, 6, 8 },
109 { 16934400, 4, 41, 238, 8 },
110 { 18432000, 4, 3, 16, 8 },
111 { 22579200, 2, 24, 209, 8 },
112 { 24576000, 4, 1, 4, 8 },
113 { 27648000, 4, 9, 32, 8 },
114 { 33868800, 4, 41, 119, 8 },
115 { 36864000, 4, 3, 8, 8 },
116 { 45158400, 1, 24, 209, 8 },
117 { 49152000, 4, 1, 2, 8 },
118 { 50803200, 1, 27, 209, 8 },
122 static int lcc_init_enable_pll0(IpqLccClocks
*bus
)
124 IpqLccGccRegs
*gcc_regs
= bus
->gcc_apcs_regs
;
125 IpqLccPll0Regs
*pll0_regs
= bus
->lcc_pll0_regs
;
126 IpqLccPllRegs
*pll_regs
= bus
->lcc_pll_regs
;
130 regval
= 15 << LCC_PLL0_L_SHIFT
& LCC_PLL0_L_MASK
;
131 write32(&pll0_regs
->l_val
, regval
);
134 regval
= 145 << LCC_PLL0_M_SHIFT
& LCC_PLL0_M_MASK
;
135 write32(&pll0_regs
->m_val
, regval
);
138 regval
= 199 << LCC_PLL0_N_SHIFT
& LCC_PLL0_N_MASK
;
139 write32(&pll0_regs
->n_val
, regval
);
142 regval
|= LCC_PLL0_CFG_LV_MAIN_ENABLE
;
143 regval
|= LCC_PLL0_CFG_FRAC_ENABLE
;
144 write32(&pll0_regs
->config
, regval
);
147 regval
|= LCC_PLL_PCLK_SRC_PRI
;
148 write32(&pll_regs
->pri
, regval
);
151 regval
|= 1 << LCC_PLL0_MODE_BIAS_CNT_SHIFT
&
152 LCC_PLL0_MODE_BIAS_CNT_MASK
;
153 regval
|= 8 << LCC_PLL0_MODE_LOCK_CNT_SHIFT
&
154 LCC_PLL0_MODE_LOCK_CNT_MASK
;
155 write32(&pll0_regs
->mode
, regval
);
157 regval
= read32(&gcc_regs
->apcs
);
158 regval
|= GCC_PLL_APCS_PLL4_ENABLE
;
159 write32(&gcc_regs
->apcs
, regval
);
161 regval
= read32(&pll0_regs
->mode
);
162 regval
|= LCC_PLL0_MODE_FSM_VOTE_ENABLE
;
163 write32(&pll0_regs
->mode
, regval
);
167 regval
= read32(&pll0_regs
->status
);
168 if (regval
& LCC_PLL0_STAT_ACTIVE_MASK
)
171 printk(BIOS_ERR
, "%s: error enabling PLL4 clock\n", __func__
);
175 static int lcc_init_enable_ahbix(IpqLccClocks
*bus
)
177 IpqLccAhbixRegs
*ahbix_regs
= bus
->lcc_ahbix_regs
;
181 regval
|= 1 << LCC_AHBIX_MD_M_VAL_SHIFT
& LCC_AHBIX_MD_M_VAL_MASK
;
182 regval
|= 252 << LCC_AHBIX_MD_NOT_2D_VAL_SHIFT
&
183 LCC_AHBIX_MD_NOT_2D_VAL_MASK
;
184 write32(&ahbix_regs
->md
, regval
);
187 regval
|= 253 << LCC_AHBIX_NS_N_VAL_SHIFT
& LCC_AHBIX_NS_N_VAL_MASK
;
188 regval
|= LCC_AHBIX_NS_CRC_ENABLE
;
189 regval
|= LCC_AHBIX_NS_GFM_SEL_MNC
;
190 regval
|= LCC_AHBIX_NS_MNC_CLK_ENABLE
;
191 regval
|= LCC_AHBIX_NS_MNC_ENABLE
;
192 regval
|= LCC_AHBIX_NS_MNC_MODE_DUAL
;
193 regval
|= LCC_AHBIX_NS_PREDIV_BYPASS
;
194 regval
|= LCC_AHBIX_NS_MN_SRC_LPA
;
195 write32(&ahbix_regs
->ns
, regval
);
199 regval
= read32(&ahbix_regs
->status
);
200 if (regval
& LCC_AHBIX_STAT_AIF_CLK_MASK
)
203 printk(BIOS_ERR
, "%s: error enabling AHBIX clock\n", __func__
);
207 static int lcc_init_mi2s(IpqLccClocks
*bus
, unsigned int freq
)
209 IpqLccMi2sRegs
*mi2s_regs
= bus
->lcc_mi2s_regs
;
215 while (lcc_mi2s_freq_tbl
[i
].freq
!= 0) {
216 if (lcc_mi2s_freq_tbl
[i
].freq
== freq
)
220 if (lcc_mi2s_freq_tbl
[i
].freq
== 0) {
221 printk(BIOS_ERR
, "%s: invalid frequency given: %u\n",
226 switch (lcc_mi2s_freq_tbl
[i
].pd
) {
228 pd
= LCC_MI2S_NS_PREDIV_BYPASS
;
231 pd
= LCC_MI2S_NS_PREDIV_DIV2
;
234 pd
= LCC_MI2S_NS_PREDIV_DIV4
;
237 printk(BIOS_ERR
, "%s: invalid prediv found: %u\n", __func__
,
238 lcc_mi2s_freq_tbl
[i
].pd
);
242 m
= lcc_mi2s_freq_tbl
[i
].m
;
243 n
= ~(lcc_mi2s_freq_tbl
[i
].n
- m
);
244 d
= ~(lcc_mi2s_freq_tbl
[i
].d
* 2);
247 regval
|= m
<< LCC_MI2S_MD_M_VAL_SHIFT
& LCC_MI2S_MD_M_VAL_MASK
;
248 regval
|= d
<< LCC_MI2S_MD_NOT_2D_VAL_SHIFT
&
249 LCC_MI2S_MD_NOT_2D_VAL_MASK
;
250 write32(&mi2s_regs
->md
, regval
);
253 regval
|= n
<< LCC_MI2S_NS_N_VAL_SHIFT
& LCC_MI2S_NS_N_VAL_MASK
;
254 regval
|= LCC_MI2S_NS_BIT_DIV_DIV4
;
255 regval
|= LCC_MI2S_NS_MNC_CLK_ENABLE
;
256 regval
|= LCC_MI2S_NS_MNC_ENABLE
;
257 regval
|= LCC_MI2S_NS_MNC_MODE_DUAL
;
259 regval
|= LCC_MI2S_NS_MN_SRC_LPA
;
260 write32(&mi2s_regs
->ns
, regval
);
265 static int lcc_enable_mi2s(IpqLccClocks
*bus
)
267 IpqLccMi2sRegs
*mi2s_regs
= bus
->lcc_mi2s_regs
;
270 regval
= read32(&mi2s_regs
->ns
);
271 regval
|= LCC_MI2S_NS_OSR_CXC_ENABLE
;
272 regval
|= LCC_MI2S_NS_BIT_CXC_ENABLE
;
273 write32(&mi2s_regs
->ns
, regval
);
277 regval
= read32(&mi2s_regs
->status
);
278 if (regval
& LCC_MI2S_STAT_OSR_CLK_MASK
)
279 if (regval
& LCC_MI2S_STAT_BIT_CLK_MASK
)
282 printk(BIOS_ERR
, "%s: error enabling MI2S clocks: %u\n",
287 int audio_clock_config(unsigned int frequency
)
290 .gcc_apcs_regs
= (void *)(MSM_GCC_BASE
+ GCC_PLL_APCS_REG
),
291 .lcc_pll0_regs
= (void *)(MSM_LPASS_LCC_BASE
+ LCC_PLL0_MODE_REG
),
292 .lcc_ahbix_regs
= (void *)(MSM_LPASS_LCC_BASE
+ LCC_AHBIX_NS_REG
),
293 .lcc_mi2s_regs
= (void *)(MSM_LPASS_LCC_BASE
+ LCC_MI2S_NS_REG
),
294 .lcc_pll_regs
= (void *)(MSM_LPASS_LCC_BASE
+ LCC_PLL_PCLK_REG
),
297 if (lcc_init_enable_pll0(&bus
))
299 if (lcc_init_enable_ahbix(&bus
))
301 if (lcc_init_mi2s(&bus
, frequency
))
303 if (lcc_enable_mi2s(&bus
))