#include #include #include #include #include #include #include #define SPU SH7305_SPU #define DSP0 SH7305_DSP0 #define DSP1 SH7305_DSP1 #define CPG SH7305_CPG #define POWER SH7305_POWER static void configure(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; sleep_us_spin(1000); SPU.SPUSRST.RST = 1; sleep_us_spin(1000); /* Initially give all P memory and X memory to DSP0 */ SPU.PBANKC0 = 0x1f; SPU.PBANKC1 = 0x00; SPU.XBANKC0 = 0x7f; SPU.XBANKC1 = 0x00; /* 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; } //--- // State and driver metadata //--- static void hsave(spu_state_t *s) { s->PBANKC0 = SPU.PBANKC0; s->PBANKC1 = SPU.PBANKC1; s->XBANKC0 = SPU.XBANKC0; s->XBANKC1 = SPU.XBANKC1; } static void hrestore(spu_state_t const *s) { SPU.PBANKC0 = s->PBANKC0; SPU.PBANKC1 = s->PBANKC1; SPU.XBANKC0 = s->XBANKC0; SPU.XBANKC1 = s->XBANKC1; } gint_driver_t drv_spu = { .name = "SPU", .configure = configure, .hsave = (void *)hsave, .hrestore = (void *)hrestore, .state_size = sizeof(spu_state_t), }; GINT_DECLARE_DRIVER(16, drv_spu);