diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2020-08-07 08:04:19 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2020-08-07 15:55:31 -0400 |
commit | b3a0187416e48d80275af6be0178cef155aa03dc (patch) | |
tree | e03f1c62ff20fb0968fc1b50194a7041fe651cf2 /firmware/target/mips/ingenic_jz47xx | |
parent | eb0e41c1ccb0dcf35efa7e1434bb0e35c9df1543 (diff) | |
download | rockbox-b3a0187416e48d80275af6be0178cef155aa03dc.tar.gz rockbox-b3a0187416e48d80275af6be0178cef155aa03dc.zip |
jz4760: Major clocking improvements for audio PLL
* for <= 48KHz, BCLK must be 256*freq (ie bdiv = 4)
* for <= 96KHz, BCLK must be 128*freq (ie bdiv = 2)
* for 11/22/44/88 KHz, disable PLL1 and run off XTAL
* cut PLL1 with 12/24/48/98 KHz audio from 516->86MHz
* cut PLL1 with 8/16/32/64 KHz audio from 426->106.5MHz
This should result in significant power savings for
common 44.1KHz audio playback, and pretty good savings
for everything else.
As an added bonus:
* enable de-emphasis filters at 32, 44.1, and 48 KHz
Change-Id: Ie59067cd46c47e62abf4a32c53519efad104d6c8
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx')
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/codec-jz4760.c | 92 |
1 files changed, 55 insertions, 37 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4760.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4760.c index 95628841dc..233e6f4ed1 100644 --- a/firmware/target/mips/ingenic_jz47xx/codec-jz4760.c +++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4760.c | |||
@@ -87,10 +87,10 @@ void audiohw_preinit(void) | |||
87 | 87 | ||
88 | void audiohw_init(void) | 88 | void audiohw_init(void) |
89 | { | 89 | { |
90 | __gpio_as_func1(3*32+12); // BCK | 90 | __gpio_as_func1(3*32+12); // BCK - BCLK pin AA20 func 1 |
91 | __gpio_as_func0(3*32+13); // LRCK | 91 | __gpio_as_func0(3*32+13); // LRCK - SYNC pin W19 func 0 |
92 | __gpio_as_func2(4*32+5); // MCLK | 92 | __gpio_as_func2(4*32+5); // MCLK - SCLK_RSTN - E20 fund 2 |
93 | __gpio_as_func0(4*32+7); // DO | 93 | __gpio_as_func0(4*32+7); // DO - SDATO pin Y19 func 0 |
94 | 94 | ||
95 | pop_ctrl(0); | 95 | pop_ctrl(0); |
96 | ap_mute(true); | 96 | ap_mute(true); |
@@ -194,85 +194,96 @@ void audiohw_set_filter_roll_off(int value) | |||
194 | void pll1_init(unsigned int freq); | 194 | void pll1_init(unsigned int freq); |
195 | void pll1_disable(void); | 195 | void pll1_disable(void); |
196 | 196 | ||
197 | #if CFG_EXTAL != 12000000 | ||
198 | #error "non-12MHz XTAL needs new audio rates calculated!" | ||
199 | #endif | ||
200 | |||
197 | void audiohw_set_frequency(int fsel) | 201 | void audiohw_set_frequency(int fsel) |
198 | { | 202 | { |
199 | unsigned int pll1_speed; | 203 | unsigned int pll1_speed; |
200 | unsigned short mclk_div, bclk_div, func_mode; | 204 | unsigned short mclk_div, bclk_div, func_mode; |
205 | unsigned char dem = CS4398_DEM_NONE; | ||
201 | 206 | ||
202 | // bclk is 1..8 | 207 | // bclk is 2,3,4,6,8,12 ONLY |
203 | // mclk is 1..512 | 208 | // mclk is 1..512 |
204 | 209 | ||
210 | // for cs4398, BCLK must be 4 for single-rate, 2 for double-rate, 1 for quad-rate! | ||
211 | |||
212 | // 11.025 and 22.050 are a little wonky. | ||
205 | switch(fsel) | 213 | switch(fsel) |
206 | { | 214 | { |
207 | case HW_FREQ_8: // 0.512 MHz | 215 | case HW_FREQ_8: // 0.512 MHz |
208 | pll1_speed = 426000000; | 216 | pll1_speed = 426000000/4; |
209 | mclk_div = 52; | 217 | mclk_div = 208/4; |
210 | bclk_div = 16; | 218 | bclk_div = 4; |
211 | func_mode = 0; | 219 | func_mode = 0; |
212 | break; | 220 | break; |
213 | case HW_FREQ_11: // 0.7056 MHz | 221 | case HW_FREQ_11: // 0.7056 MHz |
214 | pll1_speed = 508000000; | 222 | pll1_speed = 0; |
215 | mclk_div = 45; | 223 | mclk_div = 272; |
216 | bclk_div = 16; | 224 | bclk_div = 4; |
217 | func_mode = 0; | 225 | func_mode = 0; |
218 | break; | 226 | break; |
219 | case HW_FREQ_12: // 0.768 MHz | 227 | case HW_FREQ_12: // 0.768 MHz |
220 | pll1_speed = 516000000; | 228 | pll1_speed = 516000000/2/3; |
221 | mclk_div = 42; | 229 | mclk_div = 168/2/3; |
222 | bclk_div = 16; | 230 | bclk_div = 4; |
223 | func_mode = 0; | 231 | func_mode = 0; |
224 | break; | 232 | break; |
225 | case HW_FREQ_16: // 1.024 MHz | 233 | case HW_FREQ_16: // 1.024 MHz |
226 | pll1_speed = 426000000; | 234 | pll1_speed = 426000000/4; |
227 | mclk_div = 52; | 235 | mclk_div = 104/4; |
228 | bclk_div = 8; | 236 | bclk_div = 4; |
229 | func_mode = 0; | 237 | func_mode = 0; |
230 | break; | 238 | break; |
231 | case HW_FREQ_22: // 1.4112 MHz | 239 | case HW_FREQ_22: // 1.4112 MHz |
232 | pll1_speed = 508000000; | 240 | pll1_speed = 0; |
233 | mclk_div = 45; | 241 | mclk_div = 136; |
234 | bclk_div = 8; | 242 | bclk_div = 4; |
235 | func_mode = 0; | 243 | func_mode = 0; |
236 | break; | 244 | break; |
237 | case HW_FREQ_24: // 1.536 MHz | 245 | case HW_FREQ_24: // 1.536 MHz |
238 | pll1_speed = 516000000; | 246 | pll1_speed = 516000000/2/3; |
239 | mclk_div = 42; | 247 | mclk_div = 84/2/3; |
240 | bclk_div = 8; | 248 | bclk_div = 4; |
241 | func_mode = 0; | 249 | func_mode = 0; |
242 | break; | 250 | break; |
243 | case HW_FREQ_32: // 2.048 MHz | 251 | case HW_FREQ_32: // 2.048 MHz |
244 | pll1_speed = 426000000; | 252 | pll1_speed = 426000000/4; |
245 | mclk_div = 52; | 253 | mclk_div = 52/4; |
246 | bclk_div = 4; | 254 | bclk_div = 4; |
255 | dem = CS4398_DEM_32000; | ||
247 | func_mode = 0; | 256 | func_mode = 0; |
248 | break; | 257 | break; |
249 | case HW_FREQ_44: // 2.8224 MHz | 258 | case HW_FREQ_44: // 2.8224 MHz |
250 | pll1_speed = 508000000; | 259 | pll1_speed = 0; |
251 | mclk_div = 45; | 260 | mclk_div = 68; |
252 | bclk_div = 4; | 261 | bclk_div = 4; |
262 | dem = CS4398_DEM_44100; | ||
253 | func_mode = 0; | 263 | func_mode = 0; |
254 | break; | 264 | break; |
255 | case HW_FREQ_48: // 3.072 MHz | 265 | case HW_FREQ_48: // 3.072 MHz |
256 | pll1_speed = 516000000; | 266 | pll1_speed = 516000000/2/3; |
257 | mclk_div = 42; | 267 | mclk_div = 42/2/3; |
258 | bclk_div = 4; | 268 | bclk_div = 4; |
269 | dem = CS4398_DEM_48000; | ||
259 | func_mode = 0; | 270 | func_mode = 0; |
260 | break; | 271 | break; |
261 | case HW_FREQ_64: // 4.096 MHz | 272 | case HW_FREQ_64: // 4.096 MHz |
262 | pll1_speed = 426000000; | 273 | pll1_speed = 426000000/4; |
263 | mclk_div = 52; | 274 | mclk_div = 52/4; |
264 | bclk_div = 2; | 275 | bclk_div = 2; |
265 | func_mode = 1; | 276 | func_mode = 1; |
266 | break; | 277 | break; |
267 | case HW_FREQ_88: // 5.6448 MHz | 278 | case HW_FREQ_88: // 5.6448 MHz |
268 | pll1_speed = 508000000; | 279 | pll1_speed = 0; |
269 | mclk_div = 45; | 280 | mclk_div = 68; |
270 | bclk_div = 2; | 281 | bclk_div = 2; |
271 | func_mode = 1; | 282 | func_mode = 1; |
272 | break; | 283 | break; |
273 | case HW_FREQ_96: // 6.144 MHz | 284 | case HW_FREQ_96: // 6.144 MHz |
274 | pll1_speed = 516000000; | 285 | pll1_speed = 516000000/2/3; |
275 | mclk_div = 42; | 286 | mclk_div = 42/2/3; |
276 | bclk_div = 2; | 287 | bclk_div = 2; |
277 | func_mode = 1; | 288 | func_mode = 1; |
278 | break; | 289 | break; |
@@ -286,13 +297,20 @@ void audiohw_set_frequency(int fsel) | |||
286 | /* 0 = Single-Speed Mode (<50KHz); | 297 | /* 0 = Single-Speed Mode (<50KHz); |
287 | 1 = Double-Speed Mode (50-100KHz); | 298 | 1 = Double-Speed Mode (50-100KHz); |
288 | 2 = Quad-Speed Mode; (100-200KHz) */ | 299 | 2 = Quad-Speed Mode; (100-200KHz) */ |
289 | cs4398_write_reg(CS4398_REG_MODECTL, (cs4398_read_reg(CS4398_REG_MODECTL) & ~CS4398_FM_MASK) | func_mode); | 300 | cs4398_write_reg(CS4398_REG_MODECTL, (cs4398_read_reg(CS4398_REG_MODECTL) & ~(CS4398_FM_MASK|CS4398_DEM_MASK)) | func_mode | dem); |
290 | if (func_mode == 2) | 301 | if (func_mode == 2) |
291 | cs4398_write_reg(CS4398_REG_MISC, cs4398_read_reg(CS4398_REG_MISC) | CS4398_MCLKDIV2); | 302 | cs4398_write_reg(CS4398_REG_MISC, cs4398_read_reg(CS4398_REG_MISC) | CS4398_MCLKDIV2); |
292 | else | 303 | else |
293 | cs4398_write_reg(CS4398_REG_MISC, cs4398_read_reg(CS4398_REG_MISC) & ~CS4398_MCLKDIV2); | 304 | cs4398_write_reg(CS4398_REG_MISC, cs4398_read_reg(CS4398_REG_MISC) & ~CS4398_MCLKDIV2); |
294 | 305 | ||
295 | pll1_init(pll1_speed); | 306 | if (pll1_speed == 0) { |
307 | pll1_disable(); | ||
308 | __cpm_select_i2sclk_exclk(); | ||
309 | } else { | ||
310 | __cpm_select_i2sclk_pll(); | ||
311 | __cpm_select_i2sclk_pll1(); | ||
312 | pll1_init(pll1_speed); | ||
313 | } | ||
296 | __cpm_enable_pll_change(); | 314 | __cpm_enable_pll_change(); |
297 | __cpm_set_i2sdiv(mclk_div-1); | 315 | __cpm_set_i2sdiv(mclk_div-1); |
298 | __i2s_set_i2sdiv(bclk_div-1); | 316 | __i2s_set_i2sdiv(bclk_div-1); |