1    /*
     2     * Copyright (c) 2014, Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     */
    32    /*
    33     *  ======== Power.xdc ========
    34     *
    35     *
    36     */
    37    
    38    package ti.sysbios.family.arm.ducati.smp;
    39    
    40    import ti.sysbios.knl.Task;
    41    import ti.sysbios.knl.Semaphore;
    42    import ti.sysbios.family.arm.ducati.GateSmp;
    43    
    44    /*!
    45     *  ======== Power ========
    46     *  Power support for Ducati on OMAP4430.
    47     */
    48    @DirectCall
    49    module Power
    50    {
    51        /*! Suspend function hook. */
    52        typedef Void (*SuspendFuncHookPtr)();
    53    
    54        /*! Suspend arguments structure. */
    55        struct SuspendArgs {
    56            Bool pmMasterCore;     /*! Master core for suspend/resume? */
    57            Bool rendezvousResume; /*! Rendezvous before resume? */
    58            Int dmaChannel;        /*! SDMA channel for L2 RAM save; -1=CPU copy */
    59            UInt intMask31_0;     /*! Mask of interrupts (31-0) able to wake WFI */
    60            UInt intMask63_32;    /*! Mask of interrupts (63-32) able to wake WFI */
    61            UInt intMask79_64;    /*! Mask of interrupts (79-64) able to wake WFI */
    62        };
    63    
    64        /*! Physical address of L2 RAM */
    65        const Ptr L2RAM = 0x55020000;
    66    
    67        /*! Base address of SDMA registers */
    68        config Ptr sdmaRegs = 0x4A056000;
    69    
    70        /*! Idle the CPUs when threads blocked waiting for interrupts? */
    71        config Bool idle = false;
    72    
    73        /*! Segment to load Power's shared reset code and data */
    74        metaonly config String loadSegment = "EXT_RAM";
    75    
    76        /*! 
    77         *  Pre-suspend function hooks.  Called on Core 0 (only), before beginning 
    78         *  context save.
    79         *
    80         *  To configure a function to run as Pre suspend hook, add a statement
    81         *  like the following to the application configuration script:
    82         * 
    83         *  @p(code)
    84         *  Power.preSuspendHooks.$add("&myHook");
    85         *  @p
    86         *
    87         *  Multiple hook functions can be added following this same pattern.
    88         */
    89        config SuspendFuncHookPtr preSuspendHooks[length] = [];
    90    
    91        /*! 
    92         *  Post-suspend function hooks.  Called on Core 0 (only), after context
    93         *  restore, immediately before returning from suspend.
    94         *
    95         *  To configure a function to run as Post suspend hook, add a statement
    96         *  like the following to the application configuration script:
    97         * 
    98         *  @p(code)
    99         *  Power.postSuspendHooks.$add("&myHook");
   100         *  @p
   101         *
   102         *  Multiple hook functions can be added following this same pattern.
   103         */
   104        config SuspendFuncHookPtr postSuspendHooks[length] = [];
   105    
   106        /*!
   107         *  ======== idleCPU ========
   108         *  Function used to automatically idle the CPU in the Idle loop.
   109         *
   110         *  When the 'idle' configuration parameter is set, this function will
   111         *  be added to the list of Idle loop functions.  When called from the
   112         *  Idle loop, it will invoke the wait for interrupt (WFI) instruction,
   113         *  to idle the CPU until the next interrupt occurs.
   114         */
   115        Void idleCPU();
   116    
   117        /*!
   118         *  ======== suspend ========
   119         *  Function used for suspend/resume of the M3 cores.
   120         *
   121         *  Precondition and usage constraints: 
   122         *   
   123         *  1) Before this function is called the application must disable all 
   124         *     interrupts that are not desired to wake the CPU from WFI while 
   125         *     waiting for the core domain to go off.  
   126         *
   127         *  2) For those interrupts that are desired to wake the CPU from WFI (for
   128         *     example, the mailbox interrupt), these interrupts cannot be generated
   129         *     until the Power_suspend API has reached the point of executing WFI.
   130         *     If the interrupts happen early, while this API is saving context,
   131         *     the resulting context may be stale, and the application may not 
   132         *     resume correctly.  Two global flags (one for each M3 core) are 
   133         *     assert immediately before invoking WFI; the wakeup interrupts 
   134         *     should not be asserted until these flags are asserted (non-zero):
   135         *          ti_sysbios_family_arm_ducati_smp_readyIdleCore0
   136         *          ti_sysbios_family_arm_ducati_smp_readyIdleCore1
   137         */
   138        UInt suspend(SuspendArgs * args);
   139    
   140    internal:
   141    
   142        struct Struct8 {
   143            UInt32 a0;
   144            UInt32 a1;
   145            UInt32 a2;
   146            UInt32 a3;
   147            UInt32 a4;
   148            UInt32 a5;
   149            UInt32 a6;
   150            UInt32 a7;
   151        }
   152    
   153        struct Struct10 {
   154            UInt32 a0;
   155            UInt32 a1;
   156            UInt32 a2;
   157            UInt32 a3;
   158            UInt32 a4;
   159            UInt32 a5;
   160            UInt32 a6;
   161            UInt32 a7;
   162            UInt32 a8;
   163            UInt32 a9;
   164        }
   165    
   166        struct TablePIDS {
   167            UInt32 PID1;
   168            UInt32 PID2;
   169        }
   170    
   171        struct IPRxRegs {
   172            UInt32 IPR0;
   173            UInt32 IPR1;
   174            UInt32 IPR2;
   175            UInt32 IPR3;
   176            UInt32 IPR4;
   177            UInt32 IPR5;
   178            UInt32 IPR6;
   179            UInt32 IPR7;
   180            UInt32 IPR8;
   181            UInt32 IPR9;
   182            UInt32 IPR10;
   183            UInt32 IPR11;
   184            UInt32 IPR12;
   185            UInt32 IPR13;
   186            UInt32 IPR14;
   187            UInt32 IPR15;
   188        }
   189    
   190        struct CfgRegs {
   191            UInt32 VTOR;
   192            UInt32 AIRCR;
   193            UInt32 SCR;
   194            UInt32 CCR;
   195            UInt32 SHPR0;
   196            UInt32 SHPR4;
   197            UInt32 SHPR8;
   198            UInt32 SHCSR;
   199        }
   200    
   201        struct NVICContext {
   202            UInt32 AUXCTRL;
   203            UInt32 STCSR;
   204            UInt32 STRVR;
   205            UInt32 ISER0;
   206            UInt32 ISER1;
   207            UInt32 SCR;
   208            IPRxRegs iprRegs;
   209            CfgRegs cfgRegs;
   210        }
   211    
   212        struct ContextAMMU {
   213            UInt32 largeAddr[4];
   214            UInt32 largeXlteAddr[4];
   215            UInt32 largePolicy[4];
   216            UInt32 medAddr[2];
   217            UInt32 medXlteAddr[2];
   218            UInt32 medPolicy[2];
   219            Struct10 smallAddr;
   220            Struct10 smallXlteAddr;
   221            Struct10 smallPolicy;
   222            UInt32 mmuConfig;
   223        }
   224    
   225        struct ContextCTM {
   226            UInt32 CNTL;
   227            UInt32 STMCNTL;
   228            UInt32 STMMSTID;
   229            UInt32 STMINTVL;
   230            UInt32 STMSEL0;
   231            UInt32 TINTVLR0;
   232            UInt32 TINTVLR1;
   233            UInt32 GNBL0;
   234            Struct8 control;
   235        }
   236    
   237        struct CpuRegs {
   238            UInt32 R4;
   239            UInt32 R5;
   240            UInt32 R6;
   241            UInt32 R7;
   242            UInt32 R8;
   243            UInt32 R9;
   244            UInt32 R10;
   245            UInt32 R11;
   246            UInt32 LR;
   247            UInt32 CONTROL;
   248            UInt32 BASEPRI;
   249            UInt32 MSP;
   250            UInt32 pSP;
   251        }
   252    
   253        struct PrivateContext {
   254            CpuRegs privateCPU;
   255            NVICContext privateNVIC;
   256            TablePIDS privatePIDS;
   257        } 
   258    
   259        struct UnicacheConfig {
   260            UInt32 L1_CONFIG;
   261            UInt32 L1_OCP;
   262        }
   263    
   264        struct SubsystemContext {
   265            UInt32 WUGEN_MEVT0;
   266            UInt32 WUGEN_MEVT1;
   267            UnicacheConfig cacheConfig;
   268            ContextAMMU ammuConfig;
   269            ContextCTM ctmConfig;
   270        }
   271    
   272        struct DucatiContext {
   273            PrivateContext masterContext;
   274            PrivateContext slaveContext;
   275            SubsystemContext ssContext;
   276        }
   277    
   278        struct SdmaRegs {
   279            volatile UInt32 CCR;
   280            UInt32 CLNK;
   281            UInt32 CICR;
   282            UInt32 CSR;
   283            UInt32 CSDP;
   284            UInt32 CEN;
   285            UInt32 CFN;
   286            UInt32 CSSA;
   287            UInt32 CDSA;
   288            UInt32 CSEI;
   289            UInt32 CSFI;
   290            UInt32 CDEI;
   291            UInt32 CDFI;
   292        }
   293    
   294        config Bool enable = true;
   295    
   296        config GateSmp.Handle gate;
   297    
   298        config Task.Handle taskCore0;
   299        
   300        config Task.Handle taskCore1;
   301    
   302        config Semaphore.Handle semCore0;
   303    
   304        config Semaphore.Handle semCore1;
   305    
   306        /*!
   307         *  ======== taskFxnCore0 ========
   308         *  Task function that will invoke Power_doSuspend() on Core 0.
   309         */
   310        @DirectCall
   311        Void taskFxnCore0(UArg arg1, UArg arg2);
   312    
   313        /*!
   314         *  ======== taskFxnCore1 ========
   315         *  Task function that will invoke Power_doSuspend() on Core 1.
   316         */
   317        @DirectCall
   318        Void taskFxnCore1(UArg arg1, UArg arg2);
   319    
   320        /*!
   321         *  ======== doSuspend ========
   322         *  Function to "do" the actual suspend/resume.
   323         */
   324        @DirectCall
   325        UInt doSuspend(SuspendArgs * args);
   326    
   327        /*!
   328         *  ======== saveCpuRegs ========
   329         *  Function used to save parent-preserved CPU register context, assert
   330         *  ready to idle flag, and invoke WFI.
   331         */
   332        UInt32 saveCpuRegs(Ptr saveAddress, Ptr readyFlag);
   333    
   334        /*
   335         *  ======== Module_State ========
   336         */
   337        struct Module_State {
   338            UInt dmaChan0;
   339            UInt resetFlag0;
   340            UInt resetFlag1;
   341            UInt intMask31_0;
   342            UInt intMask63_32;
   343            UInt intMask79_64;
   344        }
   345    }
   346