From 180bd76d89c8f4a5eb6f7ea12b67275c0a0b81d6 Mon Sep 17 00:00:00 2001 From: Catalin Patulea Date: Tue, 20 Nov 2007 05:12:05 +0000 Subject: m:robe 500i: Add DSP (C5409) control driver and image loader. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15713 a1c6a512-1295-4272-9138-f99709370657 --- firmware/export/dm320.h | 4 +- firmware/target/arm/tms320dm320/dsp-dm320.c | 146 +++++++++++++++++++++ firmware/target/arm/tms320dm320/dsp-target.h | 29 ++++ .../target/arm/tms320dm320/dsp_image_helloworld.h | 30 +++++ 4 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 firmware/target/arm/tms320dm320/dsp-dm320.c create mode 100644 firmware/target/arm/tms320dm320/dsp-target.h create mode 100644 firmware/target/arm/tms320dm320/dsp_image_helloworld.h diff --git a/firmware/export/dm320.h b/firmware/export/dm320.h index 57561dc7d3..6da09c29a4 100644 --- a/firmware/export/dm320.h +++ b/firmware/export/dm320.h @@ -223,8 +223,8 @@ #define IO_GIO_CARD_ST DM320_REG(0x05B0) /* DSP Controller */ -#define IO_DSPC_HPIB_CONTROL 0x0600 -#define IO_DSPC_HPIB_STATUS 0x0602 +#define IO_DSPC_HPIB_CONTROL DM320_REG(0x0600) +#define IO_DSPC_HPIB_STATUS DM320_REG(0x0602) /* OSD Controller */ #define IO_OSD_MODE DM320_REG(0x0680) diff --git a/firmware/target/arm/tms320dm320/dsp-dm320.c b/firmware/target/arm/tms320dm320/dsp-dm320.c new file mode 100644 index 0000000000..673182f3fc --- /dev/null +++ b/firmware/target/arm/tms320dm320/dsp-dm320.c @@ -0,0 +1,146 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 Catalin Patulea + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "cpu.h" +#include "system.h" +#include "debug.h" +#include "dsp-target.h" + +/* A "DSP image" is an array of these, terminated by raw_data_size_half = 0. */ +struct dsp_section { + const unsigned short *raw_data; + unsigned short physical_addr; + unsigned short raw_data_size_half; +}; + +/* Must define struct dsp_section before including the image. */ +#include "dsp_image_helloworld.h" + +#ifdef DEBUG +static void dsp_status(void) { + unsigned short addr_7fff = DSP_(0x7fff); + unsigned short hpib_ctl = IO_DSPC_HPIB_CONTROL; + unsigned short hpib_stat = IO_DSPC_HPIB_STATUS; + char buffer1[80], buffer2[80]; + + DEBUGF("dsp_status(): clkc_hpib=%u clkc_dsp=%u", + !!(IO_CLK_MOD0 & (1 << 11)), !!(IO_CLK_MOD0 & (1 << 10))); + + DEBUGF("dsp_status(): irq_dsphint=%u scratch_status=0x%04x" + " acked=%04x", + (IO_INTC_IRQ0 >> IRQ_DSPHINT) & 1, DSP_(_status), DSP_(_acked)); +#define B(f,w,b,m) if ((w & (1 << b)) == 0) \ + strcat(f, "!"); \ + strcat(f, #m "|"); + strcpy(buffer1, ""); + B(buffer1, hpib_ctl, 0, EN); + B(buffer1, hpib_ctl, 3, NMI); + B(buffer1, hpib_ctl, 5, EXCHG); + B(buffer1, hpib_ctl, 7, DINT0); + B(buffer1, hpib_ctl, 8, DRST); + B(buffer1, hpib_ctl, 9, DHOLD); + B(buffer1, hpib_ctl, 10, BIO); + + strcpy(buffer2, ""); + B(buffer2, hpib_stat, 8, HOLDA); + B(buffer2, hpib_stat, 12, DXF); + + DEBUGF("dsp_status(): hpib: ctl=%s stat=%s", buffer1, buffer2); +#undef B +} +#endif + +static void dsp_reset(void) { + DSP_(0x7fff) = 0xdead; + + IO_DSPC_HPIB_CONTROL &= ~(1 << 8); + /* HPIB bus cycles will lock up the ARM in here. Don't touch DSP RAM. */ + nop; nop; + IO_DSPC_HPIB_CONTROL |= 1 << 8; + + /* TODO: Timeout. */ + while (DSP_(0x7fff) != 0); +} + +void dsp_wake(void) { + /* If this is called concurrently, we may overlap setting and resetting the + bit, which causes lost interrupts to the DSP. */ + int old_level = set_irq_level(IRQ_DISABLED); + + /* The first time you INT0 the DSP, the ROM loader will branch to your RST + handler. Subsequent times, your INT0 handler will get executed. */ + IO_DSPC_HPIB_CONTROL &= ~(1 << 7); + nop; nop; + IO_DSPC_HPIB_CONTROL |= 1 << 7; + + set_irq_level(old_level); +} + +static void dsp_load(const struct dsp_section *im) { + while (im->raw_data_size_half) { + volatile unsigned short *data_ptr = &DSP_(im->physical_addr); + unsigned int i; + + /* Use 16-bit writes. */ + if (im->raw_data) { + DEBUGF("dsp_load(): loading %u words at 0x%04x (0x%08lx)", + im->raw_data_size_half, im->physical_addr, + (unsigned long)data_ptr); + + for (i = 0; i < im->raw_data_size_half; i++) { + data_ptr[i] = im->raw_data[i]; + } + } else { + DEBUGF("dsp_load(): clearing %u words at 0x%04x (0x%08lx)", + im->raw_data_size_half, im->physical_addr, + (unsigned long)data_ptr); + + for (i = 0; i < im->raw_data_size_half; i++) { + data_ptr[i] = 0; + } + } + + im++; + } +} + +void dsp_init(void) { + IO_INTC_IRQ0 = 1 << 11; + IO_INTC_EINT0 |= 1 << 11; + + dsp_reset(); + dsp_load(dsp_image_helloworld); +} + +void DSPHINT(void) { + unsigned int i; + char buffer[80]; + + IO_INTC_IRQ0 = 1 << 11; + + /* DSP stores one character per word. */ + for (i = 0; i < sizeof(buffer); i++) { + buffer[i] = (&DSP_(_status))[i]; + } + + /* Release shared area to DSP. */ + dsp_wake(); + + DEBUGF("DSP: %s", buffer); +} diff --git a/firmware/target/arm/tms320dm320/dsp-target.h b/firmware/target/arm/tms320dm320/dsp-target.h new file mode 100644 index 0000000000..bbb36088f4 --- /dev/null +++ b/firmware/target/arm/tms320dm320/dsp-target.h @@ -0,0 +1,29 @@ +/* + * (C) Copyright 2007 Catalin Patulea + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ +#ifndef DSP_H +#define DSP_H + +/* DSP memory is mapped into ARM space via HPIB. */ +#define DSP_(addr) (*(volatile unsigned short *)(0x40000 + ((addr) << 1))) + +void dsp_init(void); +void dsp_wake(void); + +#endif diff --git a/firmware/target/arm/tms320dm320/dsp_image_helloworld.h b/firmware/target/arm/tms320dm320/dsp_image_helloworld.h new file mode 100644 index 0000000000..2879fcef7c --- /dev/null +++ b/firmware/target/arm/tms320dm320/dsp_image_helloworld.h @@ -0,0 +1,30 @@ +#ifndef DSP_IMAGE_HELLOWORLD +#define DSP_IMAGE_HELLOWORLD +/* + * This is just a dummy DSP image so that dsp-dm320.c compiles. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +static const struct dsp_section dsp_image_helloworld[] = { + {NULL, 0, 0} +}; + +/* Symbol table, usable with the DSP_() macro (see dsp-target.h). */ +#define _status 0x0000 + +#endif -- cgit v1.2.3