/* ============================================================================
 * Copyright (c) Texas Instruments Inc 2002, 2003, 2004, 2005, 2006, 2008
 *
 * Use of this software is controlled by the terms and conditions found in the
 * license agreement under which this software has been supplied.
 * ============================================================================
 */

/* ============================================================================
 * Revision History
 * ===============
 * 28-June-2006 TRR File Created.
 * 27-Oct-2008 Ported from old soc to new soc
 * ============================================================================
 */

/** @defgroup CSL_PSC_API PSC
 *
 * @section Introduction
 *
 * @subsection xxx Overview
 * Comprises several power domains to enable minimizing power dissipation for unused logic
 * on the device. The Global Power/Sleep Controller(GPSC) is used to control sleep for memories 
 * within each power domain. Additionally, clock gating to each of the logic blocks is managed by 
 * the Local Power/Sleep Controller(LPSCs) of each module. 
 * For modules with a dedicated clock or multiple clocks, the LPSC communicates with the PLL 
 * controller to enable and disable that module's clock(s) at the source. For modules that 
 * share a clock with other modules, the LPSC controls the clock gating.
 *
 *    @subsection References
 *    -# PSC User's Guide SPRUFK1.pdf (July 2008)
 *
 */

#ifndef _CSL_PSC_H_
#define _CSL_PSC_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <csl.h>
#include <cslr_psc.h>

/**
@defgroup CSL_PSC_DATASTRUCT  PSC Data Structures
@ingroup CSL_PSC_API
*/
/**
@defgroup CSL_PSC_FUNCTION  PSC Functions
@ingroup CSL_PSC_API
*/
/**
@defgroup CSL_PSC_ENUM PSC Enumerated Data Types
@ingroup CSL_PSC_API
*/

/**
 * General purpose global typedef declarations
 */

/** @addtogroup CSL_PSC_ENUM
 @{ */

/** @brief PSC module Enumeration
 * This provides the name of peripherals controlled by the PSC module.
 * 
 */
typedef enum {
    /** EMIF64 module*/
    CSL_PSC_MODULE_EMIF64      =   2,
    /** HPI module*/
    CSL_PSC_MODULE_HPI         =   3,
    /** UTOPIA module*/
    CSL_PSC_MODULE_UTOPIA      =   4,
    /** ADTF2 module*/
    CSL_PSC_MODULE_ADTF2       =   6,
    /** SRIO module*/
    CSL_PSC_MODULE_SRIO        =   7,
    /** TCP_0 module*/
    CSL_PSC_MODULE_TCP2_0      =   8,
    /** TCP_1 module */
    CSL_PSC_MODULE_TCP2_1      =   9,
    /** VCP2 module */
    CSL_PSC_MODULE_VCP2        =   10
} CSL_PscPeripherals;

/** @brief PSC Power domain Enumeration
 * This provides the name of peripherals controlled by the PSC module.
 * 
 */
typedef enum {
    /** Always-On power domain for core components & most pheriperals logic */
    CSL_PSC_PWRDMN_ALWAYSON        =   0,
    /** Proxy A power domain for SRIO */
    CSL_PSC_PWRDMN_PROXYA          =   1,
    /** Proxy B power domain for TCP2_0 */
    CSL_PSC_PWRDMN_PROXYB          =   2,
    /** Proxy C power domain for TCP2_1 */
    CSL_PSC_PWRDMN_PROXYC          =   3,
    /** Proxy D power domain for VCP2 */
    CSL_PSC_PWRDMN_PROXYD          =   4
}CSL_PscPowerDomain;

/**
 *  @brief This enum describes the commands used to control the power/sleep 
 *  controller through CSL_pscHwControl()
 */
typedef enum {
    /**
     * @brief   Enable clock for the specified module
     * @param   CSL_PscPeripherals *
     */
    CSL_PSC_CMD_ENABLE_MODULE = 0,

    /**
     * @brief   Enable Power domain-n GO transition
     * @param   CSL_PscPowerDomain *
     */
    CSL_PSC_CMD_PWRDMN_TRNS = 1,

    /**
     * @brief   Enable Power domain-n 
     * @param   CSL_PscPowerDomain *
     */
    CSL_PSC_CMD_ENABLE_PWRDMN = 2

} CSL_PscHwControlCmd;

/**
 *  @brief This enum describes the commands used to get status of various 
 *  parameters of the power/sleep controller. These values are used in 
 *  CSL_pscGetHwStatus()
 */
typedef enum {
    /**
     * @brief   Gets the current status of the specified module 
     * @param   CSL_PscmoduleState *
     */
    CSL_PSC_QUERY_MODULE_STAT       = 0,

    /**
     * @brief   Gets the status of the selected power domain
     * @param   CSL_PscPwrdmnState *
     */
    CSL_PSC_QUERY_PWRDMN_STAT        = 1,
    /**
     * @brief   Gets the transition status of the selected power domain
     * @param   CSL_PscPwrdmnTransState*
     */
    CSL_PSC_QUERY_PWRDMN_TRANS_STAT  = 2

    
} CSL_PscHwStatusQuery;

/**
@} */

/**
\addtogroup CSL_PSC_DATASTRUCT
@{ */

/** @brief PSC power domain status structure 
 * This provides the status of the specified Power Domain.
 * 
 */
typedef struct {
    
    /** Power Domain to be selected */
    CSL_PscPowerDomain  pwrDmn;
    /** Status of the Power Domain*/
    Bool               state;
    
}CSL_PscPwrdmnState;

/** @brief PSC powr domain transition status structure 
 * This provides the transition status of the specified Power Domain.
 * 
 */
typedef struct {
    
    /** Power Domain to be selected */
    CSL_PscPowerDomain  pwrDmn;
    /** Status of the Power Domain*/
    Bool                status;
    
}CSL_PscPwrDmnTransState;

/** @brief PSC module status structure 
 * This provides the status of the specified module.
 * 
 */
typedef struct {
    
    /** Module to be selected */
    CSL_PscPeripherals module;
    /** Status of the module*/
    Uint8             state;
    
}CSL_PscmoduleState;

/**
 * @brief Module specific context information. Present implementation of 
 *        Power and Sleep Controller CSL doesn't have any context information.
 */
typedef struct {
    /** Context information of Power and Sleep Controller CSL.
     *  The below declaration is just a place-holder for future implementation.
     */
    Uint16 contextInfo;
} CSL_PscContext;

/** @brief Module specific parameters. Present implementation of power/sleep 
 *         controller CSL doesn't have any module specific parameters.
 */
typedef struct {
    /** Bit mask to be used for module specific parameters. The below
     *  declaration is just a place-holder for future implementation.
     */
    CSL_BitMask16 flags;
} CSL_PscParam;

/** @brief This structure contains the base-address information for the
 *         peripheral instance
 */
typedef struct {
    /** Base-address of the configuration registers of the peripheral
     */
    CSL_PscRegsOvly regs;
} CSL_PscBaseAddress;

/**
 * @brief  PSC object structure.
 */
typedef struct {
    /** Pointer to the register overlay structure of the 
      * power/sleep controller 
      */
    CSL_PscRegsOvly regs;

    /** Instance of PSC being referred by this object */
    CSL_InstNum perNum;
} CSL_PscObj;

/**
 * @brief This data type is used to return the handle to the CSL of the 
 *        power/sleep controller
 */
typedef CSL_PscObj *CSL_PscHandle;

/**
@} */

/** @addtogroup CSL_PSC_FUNCTION
 @{ */

/*******************************************************************************
 * Power and Sleep Controller global function declarations
 ******************************************************************************/

/** ============================================================================
 *   @n@b CSL_pscInit
 *
 *   @b Description
 *   @n This is the initialization function for the General purpose timer CSL.
 *      The function must be called before calling any other API from this CSL.
 *      This function is idem-potent. Currently, the function just return
 *      status CSL_SOK, without doing anything.
 *
 *   @b Arguments
 *   @verbatim
        pContext    Pointer to module-context. As PSC doesn't have any context
                    based information user is expected to pass
                    NULL.
     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li                        CSL_SOK - Always returns
 *
 *   <b> Pre Condition </b>
 *   @n  None
 *
 *   <b> Post Condition </b>
 *   @n  The CSL for PSC is initialized
 *
 *   @b Modifies
 *   @n  None
 *
 *   @b Example
 *   @verbatim
            CSL_pscInit();
     @endverbatim
 * =============================================================================
 */
CSL_Status CSL_pscInit (
    CSL_PscContext *pContext
);



/** ===========================================================================
 * @b CSL_pscOpen
 * @b Description
 * @n This function populates the peripheral data object for the PSC
 *    instance and returns a handle to the instance.
 *    The open call sets up the data structures for the particular instance
 *    of PSC device. The device can be re-opened anytime after it has been
 *    normally closed if so required. The handle returned by this call is
 *    input as an essential argument for rest of the APIs described
 *    for this module.
 *
 * @b Arguments
 * @verbatim
          pscObj          Pointer to PSC object.

          pscNum          Instance of PSC CSL to be opened.
          
          pPscParam       Module specific parameters.
          
          status          Status of the function call
   @endverbatim
 *
 * <b> Return Value </b>  CSL_PscHandle
 * @n                     Valid PSC handle will be returned if
 *                        status value is equal to CSL_SOK.
 *
 * <b> Pre Condition </b>
 * @n  The PSC must be successfully initialized via CSL_pscInit() before calling this function. 
 *
 * <b> Post Condition </b>
 * @n   1. The status is returned in the status variable. If status
 *         returned is
 * @li     CSL_SOK             Valid PSC handle is returned
 * @li     CSL_ESYS_FAIL       The PSC instance is invalid
 *
 *      2. Psc object structure is populated
 *
 * @b Modifies
 * @n   1. The status variable
 *
 *      2. Psc object structure
 *
 * @b Example
 * @verbatim
            CSL_status              status;
            CSL_PscObj              pscObj;
            CSL_PscHandle           hPsc;
            hPsc = CSL_pscOpen(&pscObj, CSL_PSC, NULL, &status);
            ...
   @endverbatim
 * ========================================================================== */
CSL_PscHandle CSL_pscOpen (
    CSL_PscObj   *pscObj,
    CSL_InstNum  pscNum,
    CSL_PscParam *pPscParam,
    CSL_Status   *status
);



/** ============================================================================
 *   @n@b CSL_pscGetBaseAddress
 *
 *   @b Description
 *   @n  This function gets the base address of the given PSC
 *       instance.
 *
 *   @b Arguments
 *   @verbatim
            pscNum        Specifies the instance of the PSC to be opened

            pPscParam     Psc module specific parameters

            pBaseAddress  Pointer to base address structure containing base
                          address details
     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li					CSL_SOK            Getting the base address is successful
 *   @li					CSL_ESYS_FAIL      PSC instance is not available.
 *   @li                    CSL_ESYS_INVPARAMS Invalid Parameters
 *
 *   <b> Pre Condition </b>
 *   @n  None
 *
 *   <b> Post Condition </b>
 *   @n  Base address structure is populated
 *
 *   @b Modifies
 *   @n    1. The status variable
 *
 *         2. Base address structure is modified.
 *
 *   @b Example
 *   @verbatim
        CSL_Status            status;
        CSL_PscBaseAddress    baseAddress;

        ...
        status = CSL_pscGetBaseAddress(CSL_PSC, NULL, &baseAddress);
        ...

    @endverbatim
 * ===========================================================================
 */
CSL_Status CSL_pscGetBaseAddress (
    CSL_InstNum        pscNum,
    CSL_PscParam       *pPscParam,
    CSL_PscBaseAddress *pBaseAddress
);



/** ============================================================================
 *   @n@b CSL_pscClose.c
 *
 *   @b Description
 *   @n This function marks that CSL for the PSC instance is closed.
 *      CSL for the PSC instance need to be reopened before using any
 *      PSC CSL API.
 *
 *   @b Arguments
 *   @verbatim
            hPsc   Pointer to the object that holds reference to the
                   instance of PSC requested after the call 
     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li                    CSL_SOK            - PSC is closed
 *                                               successfully
 *
 *   @li                    CSL_ESYS_BADHANDLE - The handle passed is invalid
 *
 *   <b> Pre Condition </b>
 *   @n  Both CSL_pscInit() and CSL_pscOpen() must be called successfully in order before calling CSL_pscClose(). 
 *
 *   <b> Post Condition </b>
 *   @n  1. The PSC CSL APIs can not be called until the PSC
 *          CSL is reopened again using CSL_pscOpen()
 *
 *   @b Modifies
 *   @n  Obj structure values for the instance 
 *
 *   @b Example
 *   @verbatim
           CSL_PscHandle           hPsc;
           ...
           CSL_pscClose(hPsc);
     @endverbatim
 * ===========================================================================
 */
CSL_Status CSL_pscClose (
    CSL_PscHandle hPsc
);

/** ============================================================================
 *   @n@b CSL_pscHwControl
 *
 *   @b Description
 *   @n This function performs various control operations on the PSC instance,
 *      based on the command passed.
 *
 *   @b Arguments
 *   @verbatim
            hPsc         Handle to the PSC instance

            cmd          Operation to be performed on the PSC

            arg          Optional argument as per the control command

     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li                    CSL_SOK            - Command execution successful.
 *   @li                    CSL_ESYS_BADHANDLE - Invalid handle
 *   @li                    CSL_ESYS_INVCMD    - Invalid command
 *
 *   <b> Pre Condition </b>
 *   @n  Both CSL_pscInit() and CSL_pscOpen() must be called successfully in order before calling this function.
 *
 *   <b> Post Condition </b>
 *   @n  Registers of the PSC instance are configured according to the command
 *       and the command arguments. The command determines which registers are
 *       modified.
 *
 *   @b Modifies
 *   @n Registers determined by the command
 *
 *   @b Example
 *   @verbatim
 
        CSL_Status     status;
        CSL_PscHandle  hPsc;
        CSL_PscObj     pscObj;

        CSL_pscInit(NULL);
        hPsc = CSL_pscOpen(&pscObj, CSL_PSC, NULL, &status); 
 
        ...
        status = CSL_pscHwControl(hPsc,CSL_PSC_CMD_ENABLE_MODULE,NULL);
        ...

     @endverbatim
 * ===========================================================================
 */
CSL_Status CSL_pscHwControl(
    CSL_PscHandle       hPsc,
    CSL_PscHwControlCmd cmd,
    void                *cmdArg
);



/** ===========================================================================
 *   @n@b CSL_pscGetHwStatus
 *
 *   @b Description
 *   @n This function is used to get the value of various parameters of the
 *      PSC instance. The value returned depends on the query passed.
 *
 *   @b Arguments
 *   @verbatim
            hPsc            Handle to the PSC instance

            query           Query to be performed

            response        Pointer to buffer to return the data requested by
                            the query passed
     @endverbatim
 *
 *   <b> Return Value </b>  CSL_Status
 *   @li                    CSL_SOK            - Successful completion of the
 *                                               query
 *
 *   @li                    CSL_ESYS_BADHANDLE - Invalid handle
 *
 *   @li                    CSL_ESYS_INVQUERY  - Query command not supported
 *
 *   <b> Pre Condition </b>
 *   @n  Both CSL_pscInit() and CSL_pscOpen() must be called successfully in order before calling this function.
 *
 *   <b> Post Condition </b>
 *       Data requested by the query is returned through the variable "response"
 *
 *   @b Modifies
 *   @n  The input argument "response" is modified
 *
 *   @b Example
 *   @verbatim
        CSL_Status     status;
        CSL_PscHandle  hPsc;
        CSL_PscObj     pscObj;
        Uint32         count;

        CSL_pscInit(NULL);
        hPsc = CSL_pscOpen(&pscObj, CSL_PSC, NULL, &status); 

        ...

        status = CSL_pscGetHwStatus(hPsc, CSL_PSC_QUERY_MODULE_STAT,
                                    &count);
        ... 
     @endverbatim
 * ============================================================================
 */
CSL_Status CSL_pscGetHwStatus (
    CSL_PscHandle        hPsc,
    CSL_PscHwStatusQuery query,
    void                 *response
);
/**
@} */

#ifdef __cplusplus
}
#endif

#endif  /* _CSL_PSC_H_ */

