/*
 * Copyright 2020-2024 Yuntu Microelectronics Co., Ltd.
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

/*!
 * @file pac_driver.h
 */

#ifndef PAC_DRIVER_H
#define PAC_DRIVER_H

#include <stddef.h>
#include <stdbool.h>
#include "device_registers.h"
#include "status.h"


/*!
 * @ingroup pac_drv
 * @{
 */

/*******************************************************************************
 * Enumerations.
 ******************************************************************************/
typedef enum
{
    PAC_UNLOCK = 0,
    PAC_SOFT_LOCK = 1,
    PAC_HARD_LOCK = 2
} pac_lock_t;

typedef enum
{
    PAC_READ_ACCESS = 0,
    PAC_WRITE_ACCESS = 1
} pac_access_t;

/*!
 * @brief PAC Access Control Policy(ACP) Configuration
 * | ACP | Secure Privileged | Secure User | Non-Secure Privileged | Non-Secure User |
 * | --- | ----------------  | ----------- | ----------            | --------------- |
 * | 0   | ---               | ---         | ---                   | ---             |
 * | 1   | R                 | R           | ---                   | ---             |
 * | 2   | RW                | ---         | ---                   | ---             |
 * | 3   | RW                | RW          | ---                   | ---             |
 * | 4   | RW                | RW          | R                     | ---             |
 * | 5   | RW                | RW          | R                     | R               |
 * | 6   | RW                | RW          | RW                    | ---             |
 * | 7   | RW                | RW          | RW                    | RW              |
 * Example:
 * When ACP is 1, corresponding slave can be accessed by read(R) operation only in the
 * Secure Privileged mode and Secure User mode.
 */
typedef enum
{
    PAC_ACP0 = 0,
    PAC_ACP1 = 1,
    PAC_ACP2 = 2,
    PAC_ACP3 = 3,
    PAC_ACP4 = 4,
    PAC_ACP5 = 5,
    PAC_ACP6 = 6,
    PAC_ACP7 = 7,
} pac_acp_t;

typedef enum
{
    PAC_ATTR_SECURE_USER = 0,
    PAC_ATTR_SECURE_PRIVILEGED = 1,
    PAC_ATTR_NON_SECURE_USER = 2,
    PAC_ATTR_NON_SECURE_PRIVILEGED = 3,
} pac_attr_t;

/*!
 * @brief PAC Error Mode(EM) Configuration
 */
typedef enum
{
    PAC_ERROR_NOT_UPDATE = 0,   /*! Error log only records details of the first error */
    PAC_ERROR_UPDATE = 1,       /*! Error log records the latest error */
} pac_em_t;

/*!
 * @brief PAC Master ACP Configuration
 */
typedef struct
{
    soc_master_t master;        /*! Master ID */
    pac_acp_t acp;              /*! Access Control Policy */
} pac_macp_t;

/*!
 * @brief PAC Peripheral Slot(PS) Configuration
 */
typedef struct
{
    pac_psm_t slot;             /*! Peripheral slot */
    uint8_t num;                /*! Master number */
    pac_macp_t *macp;           /*! Master ACP configuration */
    bool semaphoreEn;           /*! Semaphore enable */
    uint8_t semaphoreNum;       /*! Master id semaphore */
} pac_psc_t;

typedef struct
{
    uint32_t num;               /*! Number of peripheral slot */
    pac_psc_t *periphSlot;      /*! Peripheral slot configuration */
    pac_em_t errorMode;         /*! Error mode */
    bool errorIntEn;            /*! Error interrupt enable */
} pac_config_t;

/*******************************************************************************
* Definitions
******************************************************************************/


/*******************************************************************************
 * API
 ******************************************************************************/
/*!
 * @name PAC Driver
 * @{
 */

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Initialize PAC
 * 
 * @param[in] config  PAC configuration
 */
void PAC_DRV_Init(pac_config_t *config);

/*!
 * @brief Deinitialize PAC
 */
void PAC_DRV_Deinit(void);

/*!
 * @brief Unlock PAC
 * 
 * @param[in] slot      PAC peripheral slot
 */
void PAC_DRV_Unlock(pac_psm_t slot);

/*!
 * @brief Lock PAC
 * 
 * @param[in] slot      PAC peripheral slot
 * @param[in] type      PAC lock type
 */
void PAC_DRV_Lock(pac_psm_t slot, pac_lock_t type);

/*!
 * @brief Enable PAC
 * 
 * @param[in] slot      PAC peripheral slot
 */
void PAC_DRV_EnablePeriphSlot(pac_psm_t slot);

/*!
 * @brief Disable PAC
 * 
 * @param[in] slot      PAC peripheral slot
 */
void PAC_DRV_DisablePeriphSlot(pac_psm_t slot);

/*!
 * @brief Get peripheral slot
 * 
 * @param[in] instance  PAC hw instance
 * @return PAC peripheral slot
 */
pac_psm_t PAC_DRV_GetErrorSlot(uint32_t instance);

/*!
 * @brief Get error master
 * 
 * @param[in] instance  PAC hw instance
 * @return PAC error master
 */
soc_master_t PAC_DRV_GetErrorMaster(uint32_t instance);

/*!
 * @brief Get error access
 * 
 * @param[in] instance  PAC hw instance
 * @return PAC error access
 */
pac_access_t PAC_DRV_GetErrorAccess(uint32_t instance);

/*!
 * @brief Get error acess control policy(ACP)
 * 
 * @param[in] instance  PAC hw instance
 * @return PAC error access control policy(ACP)
 */
pac_acp_t PAC_DRV_GetErrorAcp(uint32_t instance);

/*!
 * @brief Get error attribute
 * 
 * @param[in] instance  PAC hw instance
 * @return PAC error attribute
 */
pac_attr_t PAC_DRV_GetErrorAttribute(uint32_t instance);

/*!
 * @brief Get PAC error flag
 * 
 * @param[in] instance  PAC hw instance
 * @return PAC error flag
 */
uint8_t PAC_DRV_GetErrorFlag(uint32_t instance);

/*!
 * @brief Clear PAC error flag
 * 
 * @param[in] instance  PAC hw instance
 */
void PAC_DRV_ClearErrorFlag(uint32_t instance);

/*!
 * @brief Enable PAC interrupt
 * 
 * @param[in] instance  PAC hw instance
 */
void PAC_DRV_EnableInterrupt(uint32_t instance);

/*!
 * @brief Get PAC interrupt status
 * 
 * @param[in] instance  PAC hw instance
 * @return PAC interrupt status
 */
bool PAC_DRV_GetInterruptStatus(uint32_t instance);

/*!
 * @brief Disable PAC interrupt
 * 
 * @param[in] instance  PAC hw instance
 */
void PAC_DRV_DisableInterrupt(uint32_t instance);

/*!
 * @brief Set PAC error mode
 * 
 * @param[in] instance  PAC hw instance
 * @param[in] mode      PAC error mode
 */
void PAC_DRV_SetErrorMode(uint32_t instance, pac_em_t mode);

/*!
 * @brief Get PAC error mode
 * 
 * @param[in] instance  PAC hw instance
 * @return PAC error mode
 */
pac_em_t PAC_DRV_GetErrorMode(uint32_t instance);

/*! @}*/
#if defined(__cplusplus)
}
#endif

/*! @}*/

#endif /* PAC_DRIVER_H */
/*******************************************************************************
 * EOF
 ******************************************************************************/
