• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 
3 #include <stdint.h>
4 #include <delay.h>
5 #include <console/console.h>
6 #include <soc/clock.h>
7 #include <soc/lcc-reg.h>
8 #include <device/mmio.h>
9 
10 typedef struct {
11 	void *gcc_apcs_regs;
12 	void *lcc_pll0_regs;
13 	void *lcc_ahbix_regs;
14 	void *lcc_mi2s_regs;
15 	void *lcc_pll_regs;
16 } IpqLccClocks;
17 
18 typedef struct __packed {
19 	uint32_t apcs;
20 } IpqLccGccRegs;
21 
22 typedef struct __packed {
23 	uint32_t mode;
24 	uint32_t l_val;
25 	uint32_t m_val;
26 	uint32_t n_val;
27 	uint32_t UNUSED;
28 	uint32_t config;
29 	uint32_t status;
30 } IpqLccPll0Regs;
31 
32 typedef struct __packed {
33 	uint32_t ns;
34 	uint32_t md;
35 	uint32_t UNUSED;
36 	uint32_t status;
37 } IpqLccAhbixRegs;
38 
39 typedef struct __packed {
40 	uint32_t ns;
41 	uint32_t md;
42 	uint32_t status;
43 } IpqLccMi2sRegs;
44 
45 typedef struct __packed {
46 	uint32_t pri;
47 	uint32_t sec;
48 } IpqLccPllRegs;
49 
50 struct lcc_freq_tbl {
51 	unsigned int freq;
52 	unsigned int pd;
53 	unsigned int m;
54 	unsigned int n;
55 	unsigned int d;
56 };
57 
58 static const struct lcc_freq_tbl lcc_mi2s_freq_tbl[] = {
59 	{  1024000, 4,  1,  96, 8 },
60 	{  1411200, 4,  2, 139, 8 },
61 	{  1536000, 4,  1,  64, 8 },
62 	{  2048000, 4,  1,  48, 8 },
63 	{  2116800, 4,  2,  93, 8 },
64 	{  2304000, 4,  2,  85, 8 },
65 	{  2822400, 4,  6, 209, 8 },
66 	{  3072000, 4,  1,  32, 8 },
67 	{  3175200, 4,  1,  31, 8 },
68 	{  4096000, 4,  1,  24, 8 },
69 	{  4233600, 4,  9, 209, 8 },
70 	{  4608000, 4,  3,  64, 8 },
71 	{  5644800, 4, 12, 209, 8 },
72 	{  6144000, 4,  1,  16, 8 },
73 	{  6350400, 4,  2,  31, 8 },
74 	{  8192000, 4,  1,  12, 8 },
75 	{  8467200, 4, 18, 209, 8 },
76 	{  9216000, 4,  3,  32, 8 },
77 	{ 11289600, 4, 24, 209, 8 },
78 	{ 12288000, 4,  1,   8, 8 },
79 	{ 12700800, 4, 27, 209, 8 },
80 	{ 13824000, 4,  9,  64, 8 },
81 	{ 16384000, 4,  1,   6, 8 },
82 	{ 16934400, 4, 41, 238, 8 },
83 	{ 18432000, 4,  3,  16, 8 },
84 	{ 22579200, 2, 24, 209, 8 },
85 	{ 24576000, 4,  1,   4, 8 },
86 	{ 27648000, 4,  9,  32, 8 },
87 	{ 33868800, 4, 41, 119, 8 },
88 	{ 36864000, 4,  3,   8, 8 },
89 	{ 45158400, 1, 24, 209, 8 },
90 	{ 49152000, 4,  1,   2, 8 },
91 	{ 50803200, 1, 27, 209, 8 },
92 	{ }
93 };
94 
lcc_init_enable_pll0(IpqLccClocks * bus)95 static int lcc_init_enable_pll0(IpqLccClocks *bus)
96 {
97 	IpqLccGccRegs *gcc_regs = bus->gcc_apcs_regs;
98 	IpqLccPll0Regs *pll0_regs = bus->lcc_pll0_regs;
99 	IpqLccPllRegs *pll_regs = bus->lcc_pll_regs;
100 	uint32_t regval;
101 
102 	regval = 0;
103 	regval = 15 << LCC_PLL0_L_SHIFT & LCC_PLL0_L_MASK;
104 	write32(&pll0_regs->l_val, regval);
105 
106 	regval = 0;
107 	regval = 145 << LCC_PLL0_M_SHIFT & LCC_PLL0_M_MASK;
108 	write32(&pll0_regs->m_val, regval);
109 
110 	regval = 0;
111 	regval = 199 << LCC_PLL0_N_SHIFT & LCC_PLL0_N_MASK;
112 	write32(&pll0_regs->n_val, regval);
113 
114 	regval = 0;
115 	regval |= LCC_PLL0_CFG_LV_MAIN_ENABLE;
116 	regval |= LCC_PLL0_CFG_FRAC_ENABLE;
117 	write32(&pll0_regs->config, regval);
118 
119 	regval = 0;
120 	regval |= LCC_PLL_PCLK_SRC_PRI;
121 	write32(&pll_regs->pri, regval);
122 
123 	regval = 0;
124 	regval |= 1 << LCC_PLL0_MODE_BIAS_CNT_SHIFT &
125 			LCC_PLL0_MODE_BIAS_CNT_MASK;
126 	regval |= 8 << LCC_PLL0_MODE_LOCK_CNT_SHIFT &
127 			LCC_PLL0_MODE_LOCK_CNT_MASK;
128 	write32(&pll0_regs->mode, regval);
129 
130 	regval = read32(&gcc_regs->apcs);
131 	regval |= GCC_PLL_APCS_PLL4_ENABLE;
132 	write32(&gcc_regs->apcs, regval);
133 
134 	regval = read32(&pll0_regs->mode);
135 	regval |= LCC_PLL0_MODE_FSM_VOTE_ENABLE;
136 	write32(&pll0_regs->mode, regval);
137 
138 	mdelay(1);
139 
140 	regval = read32(&pll0_regs->status);
141 	if (regval & LCC_PLL0_STAT_ACTIVE_MASK)
142 		return 0;
143 
144 	printk(BIOS_ERR, "%s: error enabling PLL4 clock\n", __func__);
145 	return 1;
146 }
147 
lcc_init_enable_ahbix(IpqLccClocks * bus)148 static int lcc_init_enable_ahbix(IpqLccClocks *bus)
149 {
150 	IpqLccAhbixRegs *ahbix_regs = bus->lcc_ahbix_regs;
151 	uint32_t regval;
152 
153 	regval = 0;
154 	regval |= 1 << LCC_AHBIX_MD_M_VAL_SHIFT & LCC_AHBIX_MD_M_VAL_MASK;
155 	regval |= 252 << LCC_AHBIX_MD_NOT_2D_VAL_SHIFT &
156 			LCC_AHBIX_MD_NOT_2D_VAL_MASK;
157 	write32(&ahbix_regs->md, regval);
158 
159 	regval = 0;
160 	regval |= 253 << LCC_AHBIX_NS_N_VAL_SHIFT & LCC_AHBIX_NS_N_VAL_MASK;
161 	regval |= LCC_AHBIX_NS_CRC_ENABLE;
162 	regval |= LCC_AHBIX_NS_GFM_SEL_MNC;
163 	regval |= LCC_AHBIX_NS_MNC_CLK_ENABLE;
164 	regval |= LCC_AHBIX_NS_MNC_ENABLE;
165 	regval |= LCC_AHBIX_NS_MNC_MODE_DUAL;
166 	regval |= LCC_AHBIX_NS_PREDIV_BYPASS;
167 	regval |= LCC_AHBIX_NS_MN_SRC_LPA;
168 	write32(&ahbix_regs->ns, regval);
169 
170 	mdelay(1);
171 
172 	regval = read32(&ahbix_regs->status);
173 	if (regval & LCC_AHBIX_STAT_AIF_CLK_MASK)
174 		return 0;
175 
176 	printk(BIOS_ERR, "%s: error enabling AHBIX clock\n", __func__);
177 	return 1;
178 }
179 
lcc_init_mi2s(IpqLccClocks * bus,unsigned int freq)180 static int lcc_init_mi2s(IpqLccClocks *bus, unsigned int freq)
181 {
182 	IpqLccMi2sRegs *mi2s_regs = bus->lcc_mi2s_regs;
183 	uint32_t regval;
184 	uint8_t pd, m, n, d;
185 	unsigned int i;
186 
187 	i = 0;
188 	while (lcc_mi2s_freq_tbl[i].freq != 0) {
189 		if (lcc_mi2s_freq_tbl[i].freq == freq)
190 			break;
191 		++i;
192 	}
193 	if (lcc_mi2s_freq_tbl[i].freq == 0) {
194 		printk(BIOS_ERR, "%s: invalid frequency given: %u\n",
195 		       __func__, freq);
196 		return 1;
197 	}
198 
199 	switch (lcc_mi2s_freq_tbl[i].pd) {
200 	case 1:
201 		pd = LCC_MI2S_NS_PREDIV_BYPASS;
202 		break;
203 	case 2:
204 		pd = LCC_MI2S_NS_PREDIV_DIV2;
205 		break;
206 	case 4:
207 		pd = LCC_MI2S_NS_PREDIV_DIV4;
208 		break;
209 	default:
210 		printk(BIOS_ERR, "%s: invalid prediv found: %u\n", __func__,
211 				lcc_mi2s_freq_tbl[i].pd);
212 		return 1;
213 	}
214 
215 	m = lcc_mi2s_freq_tbl[i].m;
216 	n = ~(lcc_mi2s_freq_tbl[i].n - m);
217 	d = ~(lcc_mi2s_freq_tbl[i].d * 2);
218 
219 	regval = 0;
220 	regval |= m << LCC_MI2S_MD_M_VAL_SHIFT & LCC_MI2S_MD_M_VAL_MASK;
221 	regval |= d << LCC_MI2S_MD_NOT_2D_VAL_SHIFT &
222 			LCC_MI2S_MD_NOT_2D_VAL_MASK;
223 	write32(&mi2s_regs->md, regval);
224 
225 	regval = 0;
226 	regval |= n << LCC_MI2S_NS_N_VAL_SHIFT & LCC_MI2S_NS_N_VAL_MASK;
227 	regval |= LCC_MI2S_NS_BIT_DIV_DIV4;
228 	regval |= LCC_MI2S_NS_MNC_CLK_ENABLE;
229 	regval |= LCC_MI2S_NS_MNC_ENABLE;
230 	regval |= LCC_MI2S_NS_MNC_MODE_DUAL;
231 	regval |= pd;
232 	regval |= LCC_MI2S_NS_MN_SRC_LPA;
233 	write32(&mi2s_regs->ns, regval);
234 
235 	return 0;
236 }
237 
lcc_enable_mi2s(IpqLccClocks * bus)238 static int lcc_enable_mi2s(IpqLccClocks *bus)
239 {
240 	IpqLccMi2sRegs *mi2s_regs = bus->lcc_mi2s_regs;
241 	uint32_t regval;
242 
243 	regval = read32(&mi2s_regs->ns);
244 	regval |= LCC_MI2S_NS_OSR_CXC_ENABLE;
245 	regval |= LCC_MI2S_NS_BIT_CXC_ENABLE;
246 	write32(&mi2s_regs->ns, regval);
247 
248 	udelay(10);
249 
250 	regval = read32(&mi2s_regs->status);
251 	if (regval & LCC_MI2S_STAT_OSR_CLK_MASK)
252 		if (regval & LCC_MI2S_STAT_BIT_CLK_MASK)
253 			return 0;
254 
255 	printk(BIOS_ERR, "%s: error enabling MI2S clocks: %u\n",
256 	       __func__, regval);
257 	return 1;
258 }
259 
audio_clock_config(unsigned int frequency)260 int audio_clock_config(unsigned int frequency)
261 {
262 	IpqLccClocks bus = {
263 		.gcc_apcs_regs = (void *)(MSM_GCC_BASE + GCC_PLL_APCS_REG),
264 		.lcc_pll0_regs = (void *)(MSM_LPASS_LCC_BASE + LCC_PLL0_MODE_REG),
265 		.lcc_ahbix_regs = (void *)(MSM_LPASS_LCC_BASE + LCC_AHBIX_NS_REG),
266 		.lcc_mi2s_regs = (void *)(MSM_LPASS_LCC_BASE + LCC_MI2S_NS_REG),
267 		.lcc_pll_regs = (void *)(MSM_LPASS_LCC_BASE + LCC_PLL_PCLK_REG),
268 	};
269 
270 	if (lcc_init_enable_pll0(&bus))
271 		return 1;
272 	if (lcc_init_enable_ahbix(&bus))
273 		return 1;
274 	if (lcc_init_mi2s(&bus, frequency))
275 		return 1;
276 	if (lcc_enable_mi2s(&bus))
277 		return 1;
278 
279 	return 0;
280 }
281