#ifndef QSEE_FUSE_H
#define QSEE_FUSE_H

/**
@file qsee_fuse.h
@brief Provide HW & SW Fuse functionality
*/
/*===========================================================================
   Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
   All Rights Reserved.
   Confidential and Proprietary - Qualcomm Technologies, Inc.
===========================================================================*/

/*===========================================================================

                            EDIT HISTORY FOR FILE

when       who      what, where, why
--------   ---      ------------------------------------
09/03/24    ajesu   Move HEVC disable fuse to QSEE reserved fuse
12/01/23    ajesu   Add new fuse for HEVC disable
08/23/23    sg      Added a new fuse to prevent reloading Runtime Attestaion TA
02/28/23    sg      Added a new fuse to prevent reloading mfgmodemgmt TA
12/12/22    sg      Added TZ_UEFI_RAEDY_TO_BOOT_FUSE and TZ_UEFI_EXIT_FUSE
06/05/18    pranavj TPM app separation from winsecapp
10/03/11    rv      Initial version.

===========================================================================*/

/*----------------------------------------------------------------------------
 * Include Files
 * -------------------------------------------------------------------------*/
#include <stdbool.h>
#include <stdint.h>
/** @cond */

/*----------------------------------------------------------------------------
 * Preprocessor Definitions and Constants
 * -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
 * Type Declarations
 * -------------------------------------------------------------------------*/

 /**
 QFPROM address space. The address space can contain either raw
 (uncorrected) or corrected (FEC-corrected) data.
 */
typedef enum
{
  QFPROM_ADDR_SPACE_RAW = 0,            /**< Raw address space. */
  QFPROM_ADDR_SPACE_CORR,               /**< Corrected address space. */
  QFPROM_ADDR_SPACE_SENSE,              /**< Sense address space. */
  QFPROM_ADDR_SPACE_MAX = 0x7FFFFFFF    /**< Last entry in the QFPROM_ADDR_SPACE enumerator.*/
}QFPROM_ADDR_SPACE;

/**
 Identifies the error type returned by the QFPROM API.
 */
typedef enum
{
  QFPROM_NO_ERR = 0,                            /**< Operation was successful. */
  QFPROM_DATA_PTR_NULL_ERR,                     /**< Null pointer error. */
  QFPROM_ADDRESS_INVALID_ERR,                   /**< Incorrect fuse row address. */
  QFPROM_CLOCK_SETTINGS_INVALID_ERR,            /**< Invalid settings for the
                                                     QFPROM clock. */
  QFPROM_NO_SPECIAL_ITEM_FOUND_ERR,             /**< Deprecated. */
  QFPROM_OPERATION_NOT_ALLOWED_ERR,             /**< Operation is not allowed;
                                                     the hardware is busy. */
  QFPROM_FAILED_TO_CHANGE_VOLTAGE_ERR,          /**< Error when changing the
                                                     PMIC/voltage configuration. */
  QFPROM_WRITE_ERR,                             /**< Write operation failed. */
  QFPROM_REGION_NOT_SUPPORTED_ERR,              /**< Unsupported region for
                                                     reading/blowing fuses. */
  QFPROM_REGION_NOT_READABLE_ERR,               /**< No permission to read from fuses
                                                     in the requested region. */
  QFPROM_REGION_NOT_WRITEABLE_ERR,              /**< No permission to write to fuses
                                                     in the requested region. */
  QFPROM_REGION_FEC_ENABLED_NOT_WRITEABLE_ERR,  /**< Write failed due to an
                                                     FEC-enabled fuse. */
  QFPROM_REGION_RAW_ADDR_READ_BACK_VERIFY_ERR,  /**< Verification error when writing
                                                     to a raw address space. */
  QFPROM_REGION_CORR_ADDR_READ_BACK_VERIFY_ERR, /**< Verification error when writing
                                                     to a corrected address space. */
  QFPROM_ROW_BOUNDARY_CONDITION_VERIFY_ERR,     /**< Row address is not in the
                                                     region's LSB boundary. */
  QFPROM_FEC_ERR,                               /**< FEC read error. */

  /* Please add new enum value here and keep the value incremental to the predecessor */

  QFPROM_ERR_UNKNOWN = 0x7FFFFFFF              /**<  Last entry in the QFPROM_ERR_CODE enumerator. */
}QFPROM_ERR_CODE;

/**
 * Enumeration for the SW fuses TZ supports
 */
typedef enum
{
  QSEE_HLOS_IMG_TAMPER_FUSE    = 0,   /**< Used during boot to determine
                                           if the HLOS image has been authenticated
                                           successfully. */
  QSEE_WINSECAPP_LOADED_FUSE   = 1,   /**< Used by WinSec App to prevent
                                           reloading. */
  QSEE_UEFISECAPP_LOADED_FUSE  = 2,   /**< Used by UefiSecApp to prevent
                                           reloading. */
  QSEE_MDTP_RECOVERY_MS_FUSE   = 3,   /**< Used by MDTP to prevent
                                           access to Bootloader APIs. */
  QSEE_MDTP_HLOS_MS_FUSE       = 4,   /**< Used by MDTP to prevent
                                           access to Bootloader & Recovery APIs. */
  QSEE_MSSECAPP_LOADED_FUSE    = 5,   /**< Used by MSSecApp App to prevent
                                           reloading. */
  /* QSEE_OEM_FUSE_ bits may differ from OEM to OEM and these values should not be used internally by any 
   * TZ code, nor should those definitions ever be changed by Qualcomm. Any SW fuse that is to be blown by 
   * OEMs but whose value will change the behavior of TZ needs to be allocated by Qualcomm from the 
   * QSEE_QCOM_RESERVED_FUSE_ bits. */
#ifdef TZBSP_ROUTE_HEVC_SW_FUSE
  QSEE_HEVC_DISABLE_FUSE       = 6,   /**< Used to disable HEVC 8/10 bit 
                                         IRIS accelerated encode/decode. */
#else
  QSEE_OEM_FUSE_1              = 6,   /**< Reserved fuse bit for OEMs.
                                         Don't use QSEE_OEM_FUSE_1 on compute platforms */
#endif
  QSEE_OEM_FUSE_2              = 7,   /**< Reserved fuse bit for OEMs. */

  QSEE_OEM_FUSE_3              = 8,   /**< Reserved fuse bit for OEMs. */

  QSEE_OEM_FUSE_4              = 9,   /**< Reserved fuse bit for OEMs. */

  QSEE_OEM_FUSE_5              = 10,  /**< Reserved fuse bit for OEMs. */

  QSEE_OEM_FUSE_6              = 11,  /**< Reserved fuse bit for OEMs. */

  QSEE_OEM_FUSE_7              = 12,  /**< Reserved fuse bit for OEMs. */

  QSEE_QCOM_HEVC_DISABLE_FUSE  = 13,  /**< This fuse is reserved for
                                           disable HEVC use case       */ 
  QSEE_QCOM_H264_CODEC_FUSE    = 14,  /**< H264 codec fuse */

  QSEE_QCOM_AV1_CODEC_FUSE     = 15,  /**< AV1 codec fuse */

  QSEE_QCOM_VP9_CODEC_FUSE     = 16,  /**< VP9 codec fuse */

  QSEE_QCOM_RESERVED_FUSE_5    = 17,  /**< Reserved fuse bit for QCOM. */

  QSEE_QCOM_RESERVED_FUSE_6    = 18,  /**< Reserved fuse bit for QCOM. */

  QSEE_QCOM_RESERVED_FUSE_7    = 19,  /**< Reserved fuse bit for QCOM. */

  QSEE_QCOM_RESERVED_FUSE_8    = 20,  /**< Reserved fuse bit for QCOM. */

  QSEE_TPM_LOADED_FUSE         = 21,  /**< Used by TPM app to prevent reloading.*/

  QSEE_HLOS_BL_MILESTONE_FUSE  = 22,  /**< Used to notify the bootloader milestone call. for android only,
                                        called from ABL, this is the legacy implementation, so leave it
                                        as it is for not breaking anything. */

  QSEE_HLOS_TAMPER_NOTIFY_FUSE = 23,  /**< Used to notify TZ that HLOS has been tampered. */

  QSEE_UEFI_RAEDY_TO_BOOT_FUSE = 24,  /**< Set when UEFI is ready to boot BootMgr, so far for windows only.
                                         It should be same for all platforms, but it needs UEFI core
                                         team to support setting from different UEFI SPs. */

  QSEE_UEFI_EXIT_FUSE          = 25,  /**< Set when UEFI exits, so far for windows only.
                                         It should be same for all platforms, but it needs UEFI core
                                         team to support setting from different UEFI SPs. */

  QSEE_MFGMODE_LOADED_FUSE     = 26,  /**< Used by MfgModeMgmt app to prevent reloading.*/
  
  QSEE_ATTN_APP_LOADED_FUSE    = 27,  /**< Used by runtimeattn app to prevent reloading.*/

  QSEE_NUM_SW_FUSES            = 28   /**< Number of supported SW fuses. */

} qsee_sw_fuse_t;
/** @endcond */

/*----------------------------------------------------------------------------
 * Function Declarations and Documentation
 * -------------------------------------------------------------------------*/

/**
  @addtogroup qtee_fuse
  @{
*/

/**
 * Queries whether the given software fuse is blown.
 *
 * @param[in]  fuse_num    Software fuse to query.
 * @param[out] is_blown    Pointer to a boolean indicating whether the given software fuse is blown.
 * @param[in]  is_blown_sz Return pointer size.
 *
 * @return     SUCCESS -- 0 \n
*              FAILURE -- Negative
 * @warning    This function is not thread-safe.
 */
int qsee_is_sw_fuse_blown
(
  qsee_sw_fuse_t    fuse_num,
  bool*             is_blown,
  uint32_t          is_blown_sz
);

/**
 * Changes the state of the software fuse.
 *
 * @param[in] fuse_num Software fuse to blow.
 *
 * @return    SUCCESS -- 0 \n
*             FAILURE -- Negative
 */
int qsee_blow_sw_fuse(qsee_sw_fuse_t fuse_num);

/**
 * Writes the row data to the specified QFPROM raw row address.
 *
 * @param[in] raw_row_address     Row address in the QFPROM region to which the
 *                                row data is to be written.
 *
 * @param[in] row_data[]          Array of the data (size 2x32 bits) to write into QFPROM
 *                                region.
 *
 * @param[in] bus_clk_khz         Bus clock frequency (in kHz) connected to
 *                                QFPROM. The value is ignored.
 *
 * @param[out] qfprom_api_status  Pointer to return value from the QFPROM API.
 *
 * @return  SUCCESS -- 0 \n
*           FAILURE -- Negative
 */
int qsee_fuse_write
(
  uint32_t    raw_row_address,
  uint32_t    row_data[2],
  uint32_t    bus_clk_khz,
  uint32_t*   qfprom_api_status
);

/**
 * Reads the row data from the specified QFPROM row address.
 *
 * @param[in] row_address         Row address in the QFPROM region from which the row data is read.
 *
 * @param[in] addr_type           Raw (uncorrected) or FEC-corrected data.
 *
 * @param[out] row_data[]         Array of the data (size 2x32 bits) to be read.
 *
 * @param[out] qfprom_api_status  Pointer to return value from the QFPROM API.
 *
 * @return SUCCESS -- 0 \n
*          FAILURE -- Negative
 */
int qsee_fuse_read
(
  uint32_t   row_address,
  int32_t    addr_type,
  uint32_t   row_data[2],
  uint32_t*  qfprom_api_status
);

/** @} */

#endif /* QSEE_FUSE_H */
