blob: 90c342e86891996bc25d0c1d418a2a0c67a8b0ce [file] [log] [blame]
Karl Kurbjuna56b6532007-09-30 16:29:21 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
Karl Kurbjun3c7ada52009-03-11 01:18:23 +000010 * Copyright (C) 2007 and 2009 by Karl Kurbjun
Karl Kurbjuna56b6532007-09-30 16:29:21 +000011 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Karl Kurbjuna56b6532007-09-30 16:29:21 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
Karl Kurbjun3c7ada52009-03-11 01:18:23 +000021#include <stdlib.h>
Karl Kurbjuna56b6532007-09-30 16:29:21 +000022#include "system.h"
23#include "kernel.h"
24#include "logf.h"
25#include "audio.h"
26#include "sound.h"
27#include "file.h"
Karl Kurbjun3c7ada52009-03-11 01:18:23 +000028#include "dsp-target.h"
29#include "dsp/ipc.h"
30#include "mmu-arm.h"
Michael Sevakisa2b67032011-06-29 06:37:04 +000031#include "pcm-internal.h"
Karl Kurbjuna56b6532007-09-30 16:29:21 +000032
Karl Kurbjun50c547c2011-02-06 19:33:40 +000033/* This is global to save some latency when pcm_play_dma_get_peak_buffer is
Karl Kurbjun2670e3f2009-03-24 16:40:31 +000034 * called.
35 */
Michael Sevakis1f5b9432010-05-24 16:57:48 +000036static void *start;
Karl Kurbjun2670e3f2009-03-24 16:40:31 +000037
Karl Kurbjunb7a4e102007-10-13 14:53:34 +000038void pcm_postinit(void)
Karl Kurbjuna56b6532007-09-30 16:29:21 +000039{
Karl Kurbjun50c547c2011-02-06 19:33:40 +000040 /* Configure clock divider */
41 tsc2100_writereg(CONTROL_PAGE2, TSPP1_ADDRESS, 0x1120);
42 tsc2100_writereg(CONTROL_PAGE2, TSAC3_ADDRESS, 0x0800);
43 tsc2100_writereg(CONTROL_PAGE2, TSCPC_ADDRESS, 0x3B00);
44 tsc2100_writereg(CONTROL_PAGE2, TSAC1_ADDRESS, 0x0300);
45 tsc2100_writereg(CONTROL_PAGE2, TSCSC_ADDRESS, 0xC580);
Andree Buschmannbfc129a2010-01-03 10:35:31 +000046 audiohw_postinit();
Karl Kurbjunb7a4e102007-10-13 14:53:34 +000047}
48
Karl Kurbjun2670e3f2009-03-24 16:40:31 +000049/* Return the current location in the SDRAM to SARAM transfer along with the
50 * number of bytes read in the current buffer (count). There is latency with
51 * this method equivalent to ~ the size of the SARAM buffer since there is
52 * another buffer between your ears and this calculation, but this works for
53 * key clicks and an approximate peak meter.
54 */
Karl Kurbjunb7a4e102007-10-13 14:53:34 +000055const void * pcm_play_dma_get_peak_buffer(int *count)
56{
Andree Buschmannbfc129a2010-01-03 10:35:31 +000057 int cnt = DSP_(_sdem_level);
Karl Kurbjun2670e3f2009-03-24 16:40:31 +000058
Karl Kurbjun50c547c2011-02-06 19:33:40 +000059 unsigned long addr = (unsigned long) start + cnt;
Karl Kurbjun2670e3f2009-03-24 16:40:31 +000060
61 *count = (cnt & 0xFFFFF) >> 1;
62 return (void *)((addr + 2) & ~3);
Karl Kurbjunb7a4e102007-10-13 14:53:34 +000063}
64
65void pcm_play_dma_init(void)
66{
Karl Kurbjun50c547c2011-02-06 19:33:40 +000067 IO_INTC_IRQ0 = INTR_IRQ0_IMGBUF;
68 bitset16(&IO_INTC_EINT0, INTR_EINT0_IMGBUF);
Karl Kurbjun3c7ada52009-03-11 01:18:23 +000069
Karl Kurbjune0877512009-12-12 18:36:52 +000070 /* Set this as a FIQ */
Karl Kurbjun50c547c2011-02-06 19:33:40 +000071 bitset16(&IO_INTC_FISEL0, INTR_EINT0_IMGBUF);
Karl Kurbjune0877512009-12-12 18:36:52 +000072
Karl Kurbjun50c547c2011-02-06 19:33:40 +000073 /* Enable the HPIB clock */
74 bitset16(&IO_CLK_MOD0, (CLK_MOD0_HPIB | CLK_MOD0_DSP));
75
76 IO_SDRAM_SDDMASEL = 0x24;
77
Karl Kurbjun3c7ada52009-03-11 01:18:23 +000078 IO_DSPC_HPIB_CONTROL = 1 << 10 | 1 << 9 | 1 << 8 | 1 << 7 | 1 << 3 | 1 << 0;
79
80 dsp_reset();
81 dsp_load(dsp_image);
Karl Kurbjun50c547c2011-02-06 19:33:40 +000082
83 DSP_(_dma0_stopped)=1;
Karl Kurbjun2670e3f2009-03-24 16:40:31 +000084 dsp_wake();
Karl Kurbjuna56b6532007-09-30 16:29:21 +000085}
86
Michael Sevakise69d5672008-12-12 11:01:07 +000087void pcm_dma_apply_settings(void)
Karl Kurbjuna56b6532007-09-30 16:29:21 +000088{
Andree Buschmannbfc129a2010-01-03 10:35:31 +000089 audiohw_set_frequency(pcm_fsel);
Karl Kurbjuna56b6532007-09-30 16:29:21 +000090}
91
Karl Kurbjun2670e3f2009-03-24 16:40:31 +000092/* Note that size is actually limited to the size of a short right now due to
93 * the implementation on the DSP side (and the way that we access it)
94 */
Karl Kurbjuna56b6532007-09-30 16:29:21 +000095void pcm_play_dma_start(const void *addr, size_t size)
96{
Andree Buschmannbfc129a2010-01-03 10:35:31 +000097 unsigned long sdem_addr=(unsigned long)addr - CONFIG_SDRAM_START;
Karl Kurbjun3c7ada52009-03-11 01:18:23 +000098 /* Initialize codec. */
99 DSP_(_sdem_addrl) = sdem_addr & 0xffff;
100 DSP_(_sdem_addrh) = sdem_addr >> 16;
101 DSP_(_sdem_dsp_size) = size;
Karl Kurbjun2670e3f2009-03-24 16:40:31 +0000102 DSP_(_dma0_stopped)=0;
103
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000104 dsp_wake();
Karl Kurbjuna56b6532007-09-30 16:29:21 +0000105}
106
107void pcm_play_dma_stop(void)
108{
Karl Kurbjun2670e3f2009-03-24 16:40:31 +0000109 DSP_(_dma0_stopped)=1;
Karl Kurbjun30c33822009-12-02 04:30:08 +0000110 dsp_wake();
Karl Kurbjuna56b6532007-09-30 16:29:21 +0000111}
112
Karl Kurbjunb7a4e102007-10-13 14:53:34 +0000113void pcm_play_lock(void)
Karl Kurbjuna56b6532007-09-30 16:29:21 +0000114{
Karl Kurbjunb7a4e102007-10-13 14:53:34 +0000115
Karl Kurbjuna56b6532007-09-30 16:29:21 +0000116}
117
Karl Kurbjunb7a4e102007-10-13 14:53:34 +0000118void pcm_play_unlock(void)
Karl Kurbjuna56b6532007-09-30 16:29:21 +0000119{
Karl Kurbjunb7a4e102007-10-13 14:53:34 +0000120
Karl Kurbjuna56b6532007-09-30 16:29:21 +0000121}
122
Karl Kurbjunb7a4e102007-10-13 14:53:34 +0000123void pcm_play_dma_pause(bool pause)
Karl Kurbjuna56b6532007-09-30 16:29:21 +0000124{
Karl Kurbjun2670e3f2009-03-24 16:40:31 +0000125 if (pause)
126 {
127 DSP_(_dma0_stopped)=2;
Karl Kurbjun30c33822009-12-02 04:30:08 +0000128 dsp_wake();
Karl Kurbjun2670e3f2009-03-24 16:40:31 +0000129 }
130 else
131 {
Andree Buschmannbfc129a2010-01-03 10:35:31 +0000132 DSP_(_dma0_stopped)=0;
Karl Kurbjun2670e3f2009-03-24 16:40:31 +0000133 dsp_wake();
134 }
Karl Kurbjuna56b6532007-09-30 16:29:21 +0000135}
136
137size_t pcm_get_bytes_waiting(void)
138{
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000139 return DSP_(_sdem_dsp_size)-DSP_(_sdem_level);
Karl Kurbjuna56b6532007-09-30 16:29:21 +0000140}
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000141
Karl Kurbjun5ca8bf02009-08-13 04:20:46 +0000142/* Only used when debugging */
Bertrik Sikken76f4c022010-07-31 13:41:06 +0000143static char buffer[80];
Karl Kurbjun5ca8bf02009-08-13 04:20:46 +0000144
145void DSPHINT(void) __attribute__ ((section(".icode")));
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000146void DSPHINT(void)
147{
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000148 unsigned int i;
Karl Kurbjun50c547c2011-02-06 19:33:40 +0000149 size_t size;
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000150
Karl Kurbjun50c547c2011-02-06 19:33:40 +0000151 IO_INTC_FIQ0 = INTR_IRQ0_IMGBUF;
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000152
153 switch (dsp_message.msg)
154 {
155 case MSG_DEBUGF:
156 /* DSP stores one character per word. */
157 for (i = 0; i < sizeof(buffer); i++)
158 {
159 buffer[i] = dsp_message.payload.debugf.buffer[i];
160 }
161
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000162 DEBUGF("DSP: %s", buffer);
163 break;
164
165 case MSG_REFILL:
Andree Buschmannbfc129a2010-01-03 10:35:31 +0000166 /* Buffer empty. Try to get more. */
Michael Sevakisd5699982010-05-24 16:42:32 +0000167 pcm_play_get_more_callback(&start, &size);
168
169 if (size != 0)
Andree Buschmannbfc129a2010-01-03 10:35:31 +0000170 {
171 unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START;
172 /* Flush any pending cache writes */
173 clean_dcache_range(start, size);
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000174
Andree Buschmannbfc129a2010-01-03 10:35:31 +0000175 /* set the new DMA values */
176 DSP_(_sdem_addrl) = sdem_addr & 0xffff;
177 DSP_(_sdem_addrh) = sdem_addr >> 16;
178 DSP_(_sdem_dsp_size) = size;
179
180 DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx",
181 (unsigned long)start, (unsigned long)sdem_addr);
Michael Sevakisa2b67032011-06-29 06:37:04 +0000182
183 pcm_play_dma_started_callback();
Andree Buschmannbfc129a2010-01-03 10:35:31 +0000184 }
185
186 break;
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000187 default:
Andree Buschmannbfc129a2010-01-03 10:35:31 +0000188 DEBUGF("DSP: unknown msg 0x%04x", dsp_message.msg);
189 break;
Karl Kurbjun3c7ada52009-03-11 01:18:23 +0000190 }
191
192 /* Re-Activate the channel */
193 dsp_wake();
194
195 DEBUGF("DSP: %s", buffer);
196}
197