Project

General

Profile

Introduction

MT6235 SoC features two DSP processors (master and slave).

Most probably these processors are ADSP-2181.

DSP code is executed from ROM but seems that there is possiblity to upload code over IDMA.
So far we're not able to read Code Memory using IDMA interface. Only uploading is possible.
Below is outcome from analyzing of original Sciphone G2 firmware which uses DSP processor.

Base addresses of DSP related peripherals.

Connected via APB:
  • 0x820A0000 - MCU - DSP1 (master) Shared Registers
  • 0x820C0000 - MCU - DSP2 (slave) Shared Registers
    Conected via AHB:
  • 0xA0000000 - CPU - DSP1 (master) Share RAM
  • 0xA1000000 - CPU - DSP2 (slave) Share RAM
  • 0xA2000000 - CPU - DSP1 (master) IDMA port base address
    • 0xA2000000 - DSP1 Code Memory
      • 0xA2000000 - DSP1 Code Memory Page 0
      • 0xA2010000 - DSP1 Code Memory Page 1
      • ...
      • 0xA20F0000 - DSP1 Code Memory Page 15
    • 0xA2100000 - DSP1 Program Memory
      • 0xA2100000 - DSP1 Program Memory Page 0
      • 0xA2110000 - DSP1 Program Memory Page 1
      • ...
      • 0xA21F0000 - DSP1 Program Memory Page 15
    • 0xA2200000 - DSP1 Data Memory
      • 0xA2100000 - DSP1 Data Memory Page 0
      • 0xA2110000 - DSP1 Data Memory Page 1
      • ...
      • 0xA21F0000 - DSP1 Data Memory Page 15
    • 0xA2310000 - DSP1 DDMA Short Read/Write Register

DSP Patch Unit registers (not documented in datasheet)

DPUB - DSP Patch Unit Base address (0x820E0000)
n - instruction number
  • DPUB + n*16 + 0x0 - page number
  • DPUB + n*16 + 0x4 - address
  • DPUB + n*16 + 0x8 - low 16 bits of instruction
  • DPUB + n*16 - 0xC - high 8 bits of instruction
  • DPUB + 0x100 - patch enable register

    It seems that DSP Patch Unit is able to patch only 4 instructions of DSP code memory.

    After writing 0xFF to DSP Patch Enable Register, value 0x303 appears (mask 0x300 enables master DSP, second mask 0x3 enables slave?).

    Below analysis shows that MTK firmware loads only 4 instructions over DSP Patch Unit and the rest of patch is loaded via MCU-DSP shared memory, which also proves above assumption.

    Hard to say if DSP Patch Unit is able to load patches to slave DSP, but probably not as there are MTK processors which have 2 DSP Patch Units.

Functions which work with DSP processors

idma_load() - called by Reload_DSP_Patch(), Application_Initialize()

This function is called at very early startup of platform (from init() function).

This function uses following structure describing DSP patch:

  struct dsp_ptch {
    char     patch_versionr20;
    uint16_t patch_enabler48;  /* offset 0x14 */
    uint16_t page_numberr48;   /* offset 0x74 */
    uint16_t addressr48;       /* offset 0xD4 */
    uint32_t coder48;          /* code loaded using DSP Patch Unit, offset 0x134 */
    uint32_t idma_code1r1024;  /* code loaded using IDMA to DSP1 Code Memory, offset 0x1F4 */
    uint32_t idma_code2r1024;  /* code loaded using IDMA to DSP2 Code Memory, offset 0x11F4 */
  }

  • reset DSP1
  • reset DSP2
  • write 0 to DSP Patch Unit Enable register (disable patches?)
  • write 16 values from DSP patch table to DSP Patch Unit (using page number and address fields)
  • calculate value (mask) using patch_enable field as follows (why 32 times if only 16 patches were loaded?):
mask = 0
for (i = 0; i < 32; ++i)
    mask |= dsp_ptch->patch_enable[i] << i;
  • nothing is written to DSP Patch Unit Enable register, only mask is calculated and then compared to some other value which triggers if code should be uploaded over IDMA or not
  • write 1024 instructions from idma_code[] table over IDMA under address 0xA200F000 (DSP1 Code Memory) - idma_load_cm()
  • write 1024 instructions form_idma_code2[] table over IDMA under address 0xA300F000 (DSP2 Code Memory) - idma_load_cm_d2()

L1D_DSP_Wakeup() - called by L1D_Init(), L1D_Meta_Init()

  • set DSP clock to 104MHz
  • call L1D_DSP_WritePatchConfig(1)
    • write 4 first entries from dsp_ptch[] table to DSP Patch Unit
    • write 0x303 to DSP Patch Unit Enable register (enable these patches?). This value is calculated as follows:
enable = dsp_ptch->patch_enabler0 << 8;
enable |= dsp_ptch->patch_enabler1 << 9;
enable |= dsp_ptch->patch_enabler2;
enable |= dsp_ptch->patch_enabler3 << 1;
  • set reset for DSP1
  • power up IR (?)
  • turn on DSP clock
  • wait 64 Qbits
  • write 0 to DSP1 shared RAM (0xA0000000)
  • release reset for DSP1

dsp_patch.bin - Dump of DSP patch table (8.49 KB) marcin, 05/17/2011 01:00 PM