mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 20:43:36 +01:00
spu: starter driver, supporting direct CPU access to SPU memory
This commit is contained in:
parent
8ff7d89d33
commit
3694f20d56
6 changed files with 196 additions and 2 deletions
|
@ -38,6 +38,9 @@ enum {
|
|||
INTC_RTC_ATI,
|
||||
INTC_RTC_PRI,
|
||||
INTC_RTC_CUI,
|
||||
/* SPU; interrupts from the DSPs and the SPU-bound DMA */
|
||||
INTC_SPU_DSP0,
|
||||
INTC_SPU_DSP1,
|
||||
};
|
||||
|
||||
//---
|
||||
|
|
|
@ -293,7 +293,7 @@ typedef struct
|
|||
// Forward definitions
|
||||
//---
|
||||
|
||||
/* Provided by core/gint.c */
|
||||
/* Provided by intc/intc.c */
|
||||
extern sh7705_intc_t SH7705_INTC;
|
||||
extern sh7305_intc_t SH7305_INTC;
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ typedef volatile struct
|
|||
uint32_t :1;
|
||||
uint32_t I2C :1;
|
||||
uint32_t :1;
|
||||
uint32_t SPU :1;
|
||||
uint32_t FSI_SPU :1;
|
||||
uint32_t _unknown2 :1;
|
||||
uint32_t :1;
|
||||
uint32_t LCDC :1;
|
||||
|
|
97
include/gint/mpu/spu.h
Normal file
97
include/gint/mpu/spu.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
//---
|
||||
// gint:mpu:spu - Sound Processing Unit and its DSPs
|
||||
//---
|
||||
|
||||
#ifndef GINT_MPU_SPU
|
||||
#define GINT_MPU_SPU
|
||||
|
||||
#include <gint/defs/types.h>
|
||||
|
||||
typedef volatile struct
|
||||
{
|
||||
uint32_t PBANKC0; /* Program Bank Control 0 */
|
||||
uint32_t PBANKC1; /* Program Bank Control 1 */
|
||||
pad(0x8);
|
||||
|
||||
uint32_t XBANKC0; /* X Bank Control 0 */
|
||||
uint32_t XBANKC1; /* X Bank Control 1 */
|
||||
pad(0x10);
|
||||
|
||||
lword_union(SPUSRST, /* SPU Software Reset */
|
||||
uint32_t :24;
|
||||
uint32_t DB3 :1; /* DMABUF 3 */
|
||||
uint32_t DB2 :1; /* DMABUF 2 */
|
||||
uint32_t DB1 :1; /* DMABUF 1 */
|
||||
uint32_t DB0 :1; /* DMABUF 0 */
|
||||
uint32_t :3;
|
||||
uint32_t RST :1; /* Reset */
|
||||
);
|
||||
uint32_t const SPUADR; /* SPU address */
|
||||
uint32_t const ENDIAN; /* SuperHyway endian */
|
||||
pad(0x10);
|
||||
|
||||
uint32_t GCOM[8]; /* Global Common */
|
||||
pad(0x20);
|
||||
|
||||
uint32_t const DMABUF[4]; /* Inter-DSP Communication Buffer */
|
||||
|
||||
} GPACKED(4) spu_t;
|
||||
|
||||
typedef volatile struct
|
||||
{
|
||||
uint32_t SBAR; /* Source base address */
|
||||
uint32_t SAR; /* Source address */
|
||||
uint32_t DBAR; /* Destination base address */
|
||||
uint32_t DAR; /* Destination address */
|
||||
uint32_t TCR; /* Transfer count */
|
||||
uint32_t SHPRI; /* SHway priority */
|
||||
uint32_t CHCR; /* Channel control */
|
||||
pad(0x4);
|
||||
|
||||
} GPACKED(4) spu_dsp_dma_t;
|
||||
|
||||
typedef volatile struct {
|
||||
uint32_t LSA; /* Loop start address */
|
||||
uint32_t LEA; /* Loop end address */
|
||||
pad(0x8);
|
||||
|
||||
} GPACKED(4) spu_dsp_loop_t;
|
||||
|
||||
typedef volatile struct
|
||||
{
|
||||
uint32_t DSPRST; /* DSP full reset */
|
||||
uint32_t DSPCORERST; /* DSP core reset */
|
||||
uint32_t const DSPHOLD; /* DSP hold */
|
||||
uint32_t DSPRESTART; /* DSP restart */
|
||||
pad(0x8);
|
||||
|
||||
uint32_t IEMASKC; /* CPU interrupt source mask */
|
||||
uint32_t IMASKC; /* CPU interrupt signal mask */
|
||||
uint32_t IEVENTC; /* CPU interrupt source */
|
||||
uint32_t IEMASKD; /* DSP interrupt source mask */
|
||||
uint32_t IMASKD; /* DSP interrupt signal mask */
|
||||
uint32_t IESETD; /* DSP interrupt set */
|
||||
uint32_t IECLRD; /* DSP interrupt clear */
|
||||
uint32_t OR; /* DMAC operation */
|
||||
uint32_t COM[8]; /* CPU-DSP communication */
|
||||
uint32_t BTADRU; /* Bus-through address high */
|
||||
uint32_t BTADRL; /* Bus-through address low */
|
||||
uint32_t WDATU; /* Bus-through write data high */
|
||||
uint32_t WDATL; /* Bus-through write data low */
|
||||
uint32_t RDATU; /* Bus-through read data high */
|
||||
uint32_t RDATL; /* Bus-through read data low */
|
||||
uint32_t BTCTRL; /* Bus-through mode control */
|
||||
uint32_t SPUSTS; /* SPU status */
|
||||
pad(0x88);
|
||||
|
||||
spu_dsp_dma_t DMA[3];
|
||||
pad(0x20);
|
||||
spu_dsp_loop_t LP[3];
|
||||
|
||||
} GPACKED(4) spu_dsp_t;
|
||||
|
||||
#define SH7305_SPU (*(spu_t *)0xfe2ffc00)
|
||||
#define SH7305_DSP0 (*(spu_dsp_t *)0xfe2ffd00)
|
||||
#define SH7305_DSP1 (*(spu_dsp_t *)0xfe3ffd00)
|
||||
|
||||
#endif /* GINT_MPU_SPU */
|
|
@ -56,6 +56,9 @@ static struct info {
|
|||
{ IPRK, 0xf000, IMR10, 0x04, IPRA, 0x000f },
|
||||
{ IPRK, 0xf000, IMR10, 0x02, IPRA, 0x000f },
|
||||
{ IPRK, 0xf000, IMR10, 0x01, IPRA, 0x000f },
|
||||
/* SPU */
|
||||
{ IPRC, 0x000f, IMR3, 0x04, _ /* Not supported on SH3! */ },
|
||||
{ IPRC, 0x000f, IMR4, 0x08, _ },
|
||||
};
|
||||
|
||||
|
||||
|
|
91
src/spu/spu.c
Normal file
91
src/spu/spu.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include <gint/mpu/spu.h>
|
||||
#include <gint/mpu/cpg.h>
|
||||
#include <gint/mpu/power.h>
|
||||
#include <gint/drivers.h>
|
||||
#include <gint/clock.h>
|
||||
#include <gint/intc.h>
|
||||
|
||||
#define SPU SH7305_SPU
|
||||
#define DSP0 SH7305_DSP0
|
||||
#define DSP1 SH7305_DSP1
|
||||
#define CPG SH7305_CPG
|
||||
#define POWER SH7305_POWER
|
||||
|
||||
static void init(void)
|
||||
{
|
||||
/* Block SPU interrupts from DSP0, DSP1, and their DMA */
|
||||
intc_priority(INTC_SPU_DSP0, 0);
|
||||
intc_priority(INTC_SPU_DSP1, 0);
|
||||
|
||||
/* Stop both the SPU and FSI clocks */
|
||||
CPG.FSICLKCR.lword = 0x00000103;
|
||||
CPG.SPUCLKCR.lword = 0x00000100;
|
||||
/* Enable the FSI clock, then the SPU/SPURAM clock */
|
||||
CPG.FSICLKCR.CLKSTP = 0;
|
||||
CPG.SPUCLKCR.CLKSTP = 0;
|
||||
|
||||
/* Power the clocks through MSTPCR2 */
|
||||
POWER.MSTPCR2.FSI_SPU = 0;
|
||||
|
||||
/* Reset the SPU */
|
||||
SPU.SPUSRST.RST = 0;
|
||||
SPU.SPUSRST.RST = 1;
|
||||
sleep_us_spin(1000);
|
||||
|
||||
/* Perform full DSP resets */
|
||||
DSP0.DSPCORERST = 1;
|
||||
DSP1.DSPCORERST = 1;
|
||||
DSP0.DSPRST = 0;
|
||||
DSP1.DSPRST = 0;
|
||||
sleep_us_spin(1000);
|
||||
}
|
||||
|
||||
int spu_zero(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Hardware context
|
||||
//---
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t PBANKC0, PBANKC1;
|
||||
uint32_t XBANKC0, XBANKC1;
|
||||
} ctx_t;
|
||||
|
||||
GBSS static ctx_t sys_ctx, gint_ctx;
|
||||
|
||||
static void ctx_save(void *buf)
|
||||
{
|
||||
ctx_t *ctx = buf;
|
||||
ctx->PBANKC0 = SPU.PBANKC0;
|
||||
ctx->PBANKC1 = SPU.PBANKC1;
|
||||
ctx->XBANKC0 = SPU.XBANKC0;
|
||||
ctx->XBANKC1 = SPU.XBANKC1;
|
||||
}
|
||||
|
||||
static void ctx_restore(void *buf)
|
||||
{
|
||||
ctx_t *ctx = buf;
|
||||
SPU.PBANKC0 = ctx->PBANKC0;
|
||||
SPU.PBANKC1 = ctx->PBANKC1;
|
||||
SPU.XBANKC0 = ctx->XBANKC0;
|
||||
SPU.XBANKC1 = ctx->XBANKC1;
|
||||
}
|
||||
|
||||
//---
|
||||
// Driver structure definition
|
||||
//---
|
||||
|
||||
gint_driver_t drv_spu = {
|
||||
.name = "SPU",
|
||||
.init = init,
|
||||
.sys_ctx = &sys_ctx,
|
||||
.gint_ctx = &gint_ctx,
|
||||
.ctx_save = ctx_save,
|
||||
.ctx_restore = ctx_restore,
|
||||
};
|
||||
|
||||
GINT_DECLARE_DRIVER(3, drv_spu);
|
Loading…
Reference in a new issue