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.

Is there an easy way to power down the DSP core in the OMAPL138 running linux?

Other Parts Discussed in Thread: OMAPL138

According to SPRUH77A section 9.2 table 9-1 shows that the PSC enables clocks to the C674x Megamodule by deafult.  Later in section 10.7.4.1 a detailed procedure is layed out for turning off the Megamodule clock.  Is there a nice canned solution to do this in Linux or will I need to bring up DSPLink and write a simple dsp application that manages the shutdown?

Thanks in advance for any guidance.

  • Hi,

    If you want to power down the DSP then you can pass the below arg into u-boot args,

    hwconfig=dsp:wake=no

    Ex:

    setenv bootargs 'mem=32M console=ttyS2,115200n8 ip=dhcp nfsroot=10.100.1.97:/usr/local/filesystem_omapl138 root=/dev/nfs rw rootwait  hwconfig=dsp:wake=no '

     

  • This certainly prevents u-boot from actively waking the dsp... however the dsp power domain is still enabled by default.  This is according to the technical manual and should be independent of any software activating the dsp.  In the default power on state the dsp "megamodule" is sucking down a few hundred mW just to do nothing.  I was loking for a canned way to gate clocks to the entire dsp "megamodule" to maximize power saving for configurations where I don't plan to use the dsp.

    According to the docs the dsp has to write 0x00015555 to the PDCCMD and then execute the idle instruction in order for the psc to properly transition the domain to disable...

    Am I misinterpreting the documentation?  I've tried using hwconfig=dsp:wake=no and have seen no reduction in power consumption.

    Thanks again for the help.

  • Hi,

    Yes, I agree, The u-boot will disabling the DSP wakeup only and not powering down,

    For this.

    write one function in board file that will disable the DSP,

    Just take ref code from gel file or CSL for disabling the any peripheral through LPSC and convert to linux kernel code,

    This is enable function in gel file,

    DSP is in PSC0 and Power Domain will be 1

    /*Enable Function for PSC0*/
    PSC0_LPSC_enable(unsigned int PD, unsigned int LPSC_num) {
        unsigned int j;

        if( (*(unsigned int*)(PSC0_MDSTAT+4 * LPSC_num) & 0x1F) != 0x3 ) {
          *(unsigned int*) (PSC0_MDCTL+4*LPSC_num) = (*(unsigned int*) (PSC0_MDCTL+4*LPSC_num) & 0xFFFFFFE0) | 0x0003;
          PSC0_PTCMD = 0x1<<PD;

          j = 0;
          /*Wait for power state transition to finish*/
          while( (PSC0_PTSTAT & (0x1<<PD) ) !=0) {
            if( j++ > PSC_TIMEOUT ) {
              GEL_TextOut("\tPSC0 Enable Transition Timeout on Domain %d, LPSC %d\n","Output",1,1,1,PD,LPSC_num);
              break;
            }
          }

          j = 0;
          while( (*(unsigned int*)(PSC0_MDSTAT+4 * LPSC_num) & 0x1F) !=0x3) {
            if( j++ > PSC_TIMEOUT ) {
              GEL_TextOut("\tPSC0 Enable Verify Timeout on Domain %d, LPSC %d\n","Output",1,1,1,PD,LPSC_num);
              break;
            }
          }
        }
    }

    To disable, Need to change "0x3" to "0x2" or "0x1" or "0x0" depends on the user req.

  • Hi Seth,

    Still, Do you have requirement on shutdown or power down the DSP for power saving ?

    Able to succeed !

  • Sorry for the lack of response to your previous post.  I do still have a requirement to shutdown the DSP for power saving.  I tried a few things based on your suggestion above and did not see any savings in power.  The PSC bits indicated that the DSP was successfully stopped though... This seemed strange to me so I wanted to investigate further, but haven't had the time yet.

  • Hi,

    Try to append or create one function to execute in board file to disable the DSP and update hows the power saving.

    #include <mach/psc.h>

        u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl;

    //Provide your LPSC state here;

    //    u32 next_state = PSC_STATE_ENABLE;
        u32 next_state = PSC_STATE_DISABLE;
    //    u32 next_state = PSC_STATE_SYNCRST;

    //Titus

        void __iomem *psc_base;

        unsigned int tmp,id,ctlr,domain;

    #if 1 /* DSP */
        id = 15;//LPSC no (DSP)
        ctlr = 0;//LPSC controller (PSC = 0)
        domain = 1;//LPSC power domain (PD = 1)
    #endif

        mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);

        printk(KERN_ERR "################## DSP LPSC value before = %x PSC = %d LPSC No = %d PD = %d\n",mdstat,ctlr,id,domain);


        mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
        mdctl &= ~MDSTAT_STATE_MASK;
        mdctl |= next_state;

        __raw_writel(mdctl, psc_base + MDCTL + 4 * id);

        pdstat = __raw_readl(psc_base + PDSTAT);
        if ((pdstat & 0x00000001) == 0) {
            pdctl1 = __raw_readl(psc_base + PDCTL1);
            pdctl1 |= 0x1;
            __raw_writel(pdctl1, psc_base + PDCTL1);

            ptcmd = 1 << domain;
            __raw_writel(ptcmd, psc_base + PTCMD);

            do {
                epcpr = __raw_readl(psc_base + EPCPR);
            } while ((((epcpr >> domain) & 1) == 0));

            pdctl1 = __raw_readl(psc_base + PDCTL1);
            pdctl1 |= 0x100;
            __raw_writel(pdctl1, psc_base + PDCTL1);
        } else {
            ptcmd = 1 << domain;
            __raw_writel(ptcmd, psc_base + PTCMD);
        }

        do {
            ptstat = __raw_readl(psc_base + PTSTAT);
        } while (!(((ptstat >> domain) & 1) == 0));

        do {
            mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
        } while (!((mdstat & MDSTAT_STATE_MASK) == next_state));


        mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);


        printk(KERN_ERR "################## DSP LPSC value after = %x PSC = %d LPSC No = %d PD = %d\n",mdstat,ctlr,id,domain);

        iounmap(psc_base);