This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6747 DSP/BIOS and Low Power mode

Other Parts Discussed in Thread: OMAP-L138, OMAPL138, TMS320C6748

I am using a C6747 with SDRAM on EMIF B.  Part of my application is in internal memory (for performance reasons) and part is in external memory.  I am using DSP/BIOS 5.  I would like to go into a standby mode when not processing audio with the critical part being able to turn off EMIF B and put the SDRAM in self refresh mode.  I would also successfully like to come out of this standby mode on a UART command.  Please suggest any strategies to achieve the standby mode.

Thanks,

Fawad

  • Fawad,

    For the C6748 and OMAP-L138 there is a DSP/BIOS power manager module (PWRM) that transitions the device in/out of different sleep modes, managing the PLLs and setting up self-refresh of DDR.  This support is NOT provided on C6747… but I think you can look at that source code to help you implement it for the C6747. 

    In the DSP/BIOS install you’ll find the sources for the “PMI” layer (which does this low level work) in the ti.pmi package (for example: C:\ti\bios_5_41_12_40\packages\ti\pmi\src\pmi).  Look at PMI_sleepCPU() in “pmi_slp.c”.

    Hope this helps.

    Scott

  • Scott,

    Thanks for the pointer to an example of sleep for the C67xx.  My main issue is I have DSP/BIOS code in the external memory as well as DMA going which is writing to buffers in external memory.  So will this PMI_sleepCPU take care of not accessing DSP/BIOS code which is in external memory until you come out of sleep?  How do I deal with pausing the DMA of audio samples to external memory while in sleep mode.  I was thinking of moving my audio buffers to the internal L2_CBA_RAM.  Will going to sleep still continue the DMA into the ram (internal or external)?

    Thanks,

    Fawad

  • Fawad,

    The PMI code I pointed to does NOT prevent off-chip accesses by the application.  But this code is placed into a section that must be placed on-chip.  And before this function is called, the CPU is switched to a temporary on-chip stack, to avoid any off-chip accesses.

    For the C6748, we ship a sleep6x example that transitions the device to different sleep modes.  It may help to look at that.  It can be found in the "packages\ti\bios\examples\evm6748" subdirectory of your DSP/BIOS install.

    Also, in the DSP/BIOS release notes there is a list of constraints to avoid off-chip accesses.  You’ll need to do something similar for the C6747:

    To operate within TMS320C6748 and OMAPL138 device constraints, it must be ensured that no off-chip accesses to DDR memories occur while PLL1 is bypassed.  The BIOS Power Manager (PWRM) provides two sleep modes where this constraint is a concern: PWRM_SLEEP, when PLL1 is allowed to be bypassed, and PWRM_DEEPSLEEP.  

    PWRM, and the underlying PSCL and PMI layers have been implemented with the goal of minimizing the impact of this constraint upon the user.  However, there remain some user-domain memory placement requirements, for invoking these two sleep modes.  

    The following items must be placed in on-chip memory.  Either L2 or L3 memory (referred to as IRAM or L3_CBA_RAM in BIOS configuration) can be used.  Note that L2 memory will provide faster performance compared to L3.  Where applicable, examples of how to control this with textual configuration are shown in brackets.

    1) The .bios section. [bios.MEM.BIOSSEG = prog.get("IRAM");]
    2) The .hwi_vec section. [bios.MEM.HWIVECSEG = prog.get("IRAM");]
    3) The .bss section. [bios.MEM.BSSSEG = prog.get("IRAM");]
    4) The .pmonchip section. [bios.PWRM.ONCHIPMEMSEG = prog.get("IRAM");]
    5) The .clk section (if CLK is enabled as a wakeup interrupt). [bios.CLK.OBJMEMSEG = prog.get("DDR");]
    6) The stack of the task from which PWRM_sleepDSP is being invoked. [To default all task stacks to IRAM: bios.TSK.STACKSEG = prog.get("IRAM");]
    7) The interrupt stack (the .stack section) if the HWI dispatcher is used. [bios.MEM.STACKSEG = prog.get("IRAM");]
    8) Any user-provided CLK functions (if CLK is enabled as a wakeup interrupt) (code and data).
    9) Any user-provided wakeup ISR functions (code and data).
    10) Any runtime library functions (e.g., math routines) required by the user functions that run in the context of a wakeup ISR.

    Regarding pausing the audio… how to do it depends upon your application and/or driver design.

    I don’t know whether DMA can still access internal buffers when you activate a particular sleep mode.  You might want to post a message to the device forum for this: http://e2e.ti.com/support/dsp/omap_applications_processors/default.aspx

    Scott

  • Scott,

    Thank you for your very detailed answer.  There is a lot of information in your e-mail and I need a few days to digest it.  I will be replying soon.

    Fawad

  • Scott,

    I have now decided I don't need to turn off the SDRAM but just run it at a slow speed when I go into my low power mode.  My only concern is the SDRAM clock and not the core clock of the DSP.  So I want to go from 124 MHz SDRAM clock to say 5 MHz clock.  I don't need to turn off the clocks to the SDRAM.  So all I need to know is

    1) Dynamically change PLLDIV5 EMIFB divider.

    2) Keeping critical DSP/BIOS code into internal memory so that there is little impact when I move to the 5 MHz clock.

    You have given me great pointers on what to put where for the DSP/BIOS code.  I need to know what the steps are to change the PLLDIV5 dynamically. 

    I am doing the following:

        //Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that no GO operation is currently in progress
        while(PLL0_PLLSTAT & 0x1==1){}
       
        //Program the RATIO field in PLLDIVx with the desired divide factors. In addition, make sure in this step you leave the PLLDIVx.DxEN bits set so clocks are still enabled (default)

        PLL0_PLLDIV5 = 0x8000 | PLLDIV5; // Make PLLDIV5 as bootpacket, do it for other PLLDIVx to if required

       //Set the GOSET bit in PLLCMD to 1 to initiate a new divider transition
        PLL0_PLLCMD |= 0x1;

        //Wait for the GOSTAT bit in PLLSTAT to clear to 0 (completion of phase alignment)
        while(PLL0_PLLSTAT & 0x1==1) { }

    This works and the clock goes to 5 MHz when I single step the assembler.  Running it without a breakpoint can hang it in one of the while loops.  I tried some delays between the while() tests and it works but I am not certain how long is the correct wait. 

    Also can I dynamically change the sdram clock from 124 to 5 MHz without having to put the RAM into self refresh mode?

    Thanks,

    Fawad

  • Fawad,

    OK, thanks for the update.

    I don’t know the answers to the PLL questions, and I think it will be best to post a new thread for these questions to the device forum: http://e2e.ti.com/support/dsp/omap_applications_processors/default.aspx

    Regards,
    Scott