/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright 2018-2022 Renesas Electronics Corporation All rights reserved.
*******************************************************************************/



/*******************************************************************************
 * DESCRIPTION   : emmc std header
 ******************************************************************************/
/******************************************************************************
 * @file          emmc_std.h
 * - Version      : 0.03
 * @brief         
 * .
 *****************************************************************************/
/******************************************************************************
 * History : DD.MM.YYYY Version  Description
 *         : 02.02.2022 0.01     First Release
 *         : 24.10.2022 0.02     Add supports for HS200/400
 *         : 31.10.2022 0.03     License notation change.
 *****************************************************************************/

#ifndef EMMC_STD_H__
#define EMMC_STD_H__

/* ************************ HEADER (INCLUDE) SECTION *********************** */
#include "emmc_hal.h"
#include "emmc_registers.h"
/* ***************** MACROS, CONSTANTS, COMPILATION FLAGS ****************** */

/*CSD register Macros */
#define EMMC_CSD_SPEC_VARS()        (emmc_bit_field(mmc_drv_obj.csd_data, 125,122))
#define EMMC_CSD_TRAN_SPEED()       (emmc_bit_field(mmc_drv_obj.csd_data, 103,96))

/* for sector access */
#define EMMC_SECTOR_SIZE_SHIFT      (9U)        /* 512 = 2^9 */
#define EMMC_SECTOR_PADD_MASK       ((1U << EMMC_SECTOR_SIZE_SHIFT) - 1U)
#define EMMC_SECTOR_SIZE            (512U)
#define EMMC_BLOCK_LENGTH           (512U)
#define EMMC_BLOCK_LENGTH_DW        (128U)

/* EMMC driver error code. (extended HAL_MEMCARD_RETURN) */
typedef enum
{
    EMMC_ERR                    = 0U,           /**< unknown error */
    EMMC_SUCCESS                ,               /**< OK */
    EMMC_ERR_FROM_DMAC          ,               /**< DMAC allocation error */
    EMMC_ERR_FROM_DMAC_TRANSFER ,               /**< DMAC transfer error */
    EMMC_ERR_CARD_STATUS_BIT    ,               /**< card status error. Non-masked error bit was set in the card status */
    EMMC_ERR_CMD_TIMEOUT        ,               /**< command timeout error */
    EMMC_ERR_DATA_TIMEOUT       ,               /**< data timeout error */
    EMMC_ERR_CMD_CRC            ,               /**< command CRC error */
    EMMC_ERR_DATA_CRC           ,               /**< data CRC error */
    EMMC_ERR_PARAM              ,               /**< parameter error */
    EMMC_ERR_RESPONSE           ,               /**< response error */
    EMMC_ERR_RESPONSE_BUSY      ,               /**< response busy error */
    EMMC_ERR_TRANSFER           ,               /**< data transfer error */
    EMMC_ERR_READ_SECTOR        ,               /**< read sector error */
    EMMC_ERR_WRITE_SECTOR       ,               /**< write sector error */
    EMMC_ERR_STATE              ,               /**< state error */
    EMMC_ERR_TIMEOUT            ,               /**< timeout error */
    EMMC_ERR_ILLEGAL_CARD       ,               /**< illegal card */
    EMMC_ERR_CARD_BUSY          ,               /**< Busy state */
    EMMC_ERR_CARD_STATE         ,               /**< card state error */
    EMMC_ERR_SET_TRACE          ,               /**< trace information error */
    EMMC_ERR_FROM_TIMER         ,               /**< Timer error */
    EMMC_ERR_FORCE_TERMINATE    ,               /**< Force terminate */
    EMMC_ERR_CARD_POWER         ,               /**< card power fail */
    EMMC_ERR_ERASE_SECTOR       ,               /**< erase sector error */
    EMMC_ERR_INFO2              ,               /**< exec cmd error info2 */
    RCAR_ERR                                    /**< Error judged by R-Car register */

} EMMC_ERROR_CODE;

/* Error code judged by R-car register or eMMC return*/
#define EMMC_TUNING_FAIL                    (0U)                /* Fail judged by eMMC return*/
#define TUNING_SUCCESS                      (1U)                /* Tuning success */
#define RCAR_TUNING_FAIL                    (2U)                /* Fail judged by R-car register*/

/* Response */
/** R1 */
#define EMMC_R1_ERROR_MASK                  (0xFDBFE080U)        /* Type 'E' bit and bit14(must be 0). ignore bit22 */
#define EMMC_R1_ERROR_MASK_WITHOUT_CRC      (0xFD3FE080U)        /* Ignore bit23 (Not check CRC error) */
#define EMMC_R1_STATE_MASK                  (0x00001E00U)        /* [12:9] */
#define EMMC_R1_READY                       (0x00000100U)        /* bit8 */
#define EMMC_R1_STATE_SHIFT                 (9U)

/** R4 */
#define EMMC_R4_STATUS                      (0x00008000U)

/** CSD */
#define EMMC_TRANSPEED_FREQ_UNIT_MASK       (0x07U)             /* bit[2:0] */
#define EMMC_TRANSPEED_MULT_MASK            (0x78U)             /* bit[6:3] */
#define EMMC_TRANSPEED_MULT_SHIFT           (3U)

/** OCR */
#define EMMC_HOST_OCR_VALUE                 (0x40FF8080U)
#define EMMC_OCR_STATUS_BIT                 (0x80000000U)       /* Card power up status bit */
#define EMMC_OCR_ACCESS_MODE_MASK           (0x60000000U)       /* bit[30:29] */
#define EMMC_OCR_ACCESS_MODE_SECT           (0x40000000U)

/** EXT_CSD */
#define EMMC_EXT_CSD_CARD_TYPE              (196U)
#define EMMC_EXT_CSD_PARTITION_CONFIG       (179U)
#define EMMC_EXT_CSD_PWR_CL_DDR_200_360     (253U)              /* Power class for 200MHz, DDR at VCC= 3.6V */
#define EMMC_EXT_CSD_PWR_CL_200_195         (237U)              /* Power class for 200MHz, at VCCQ =1.95V, VCC = 3.6V */
#define EMMC_EXT_CSD_PWR_CL_26_195          (201U)              /* Power class for 26MHz at 1.95V 1 R */
#define EMMC_EXT_CSD_PWR_CL_52_195          (200U)              /* Power class for 52MHz at 1.95V 1 R */

#define EMMC_EXT_CSD_CARD_TYPE_26MHZ        (0x01U)
#define EMMC_EXT_CSD_CARD_TYPE_52MHZ        (0x02U)
#define EMMC_EXT_CSD_CARD_TYPE_200MHZ       (0x10U)
#define EMMC_EXT_CSD_CARD_TYPE_400MHZ       (0x40U)

/** SWITCH (CMD6) argument */
#define EXTCSD_ACCESS_BYTE              (0x03000000U)           /* H'03000000 */

#define BUS_WIDTH_ADD                   (183U<<16U)             /* H'00b70000 */
#define HS_TIMING_ADD                   (185U<<16U)             /* H'00b90000 */
#define POW_CLASS_ADD                   (187U<<16U)             /* H'00bb0000 */

#define BUS_WIDTH_1                     (0U<<8U)                /* H'00000000 */
#define BUS_WIDTH_8                     (2U<<8U)                /* H'00000200 */
#define BUS_WIDTH_8_DDR                 (6U<<8U)                /* H'00000400 */

#define HS_TIMING_1                     (1U<<8U)                /* H'00000100 */
#define HS_TIMING_HS200                 (2U<<8U)                /* H'00000200 */
#define HS_TIMING_HS400                 (3U<<8U)                /* H'00000300 */

#define EMMC_SWITCH_HS_TIMING           (EXTCSD_ACCESS_BYTE|HS_TIMING_ADD|HS_TIMING_1)          /**< H'03b90100 */
#define EMMC_SWITCH_HS200               (EXTCSD_ACCESS_BYTE|HS_TIMING_ADD|HS_TIMING_HS200)      /**< H'03b90200 */
#define EMMC_SWITCH_HS400               (EXTCSD_ACCESS_BYTE|HS_TIMING_ADD|HS_TIMING_HS400)      /**< H'03b90300 */

#define EMMC_SWITCH_BUS_WIDTH_1         (EXTCSD_ACCESS_BYTE|BUS_WIDTH_ADD|BUS_WIDTH_1)          /**< H'03b70000 */
#define EMMC_SWITCH_BUS_WIDTH_8_DDR     (EXTCSD_ACCESS_BYTE|BUS_WIDTH_ADD|BUS_WIDTH_8_DDR)      /**< H'03b70600 */


#define EMMC_SWITCH_PARTITION_CONFIG    (0x03B30000UL)          /**< Partition config = 0x00 */

/** for st_mmc_base */
#define EMMC_MAX_RESPONSE_LENGTH        (17U)
#define EMMC_MAX_CID_LENGTH             (16U)
#define EMMC_MAX_CSD_LENGTH             (16U)
#define EMMC_MAX_EXT_CSD_LENGTH         (512U)

/* speed mode */
#define TIMING_HIGH_SPEED_OFF           (0U)
#define TIMING_HIGH_SPEED               (1U)
#define TIMING_HS200                    (2U)
#define TIMING_HS400                    (3U)

/* MMC Clock Frequency */
/* 200MHz * 1/x = output clock */
#define HS400_50MHZ                     (8U)                /* 400MHz * 1/8   = 50MHz */
#define HS400_200MHZ                    (2U)                /* 400MHz * 1/2   = 200MHz */

/* ********************** STRUCTURES, TYPE DEFINITIONS ********************* */

/* Partition id */
typedef enum
{
    PARTITION_ID_USER   = 0x0,                          /**< User Area */
    PARTITION_ID_BOOT_1 = 0x1,                          /**< boot partition 1 */
    PARTITION_ID_BOOT_2 = 0x2,                          /**< boot partition 2 */
    PARTITION_ID_RPMB   = 0x3,                          /**< Replay Protected Memory Block */
    PARTITION_ID_GP_1   = 0x4,                          /**< General Purpose partition 1 */
    PARTITION_ID_GP_2   = 0x5,                          /**< General Purpose partition 2 */
    PARTITION_ID_GP_3   = 0x6,                          /**< General Purpose partition 3 */
    PARTITION_ID_GP_4   = 0x7,                          /**< General Purpose partition 4 */
    PARTITION_ID_MASK   = 0x7                           /**< [2:0] */
} EMMC_PARTITION_ID;

/* card state in R1 response [12:9] */
typedef enum
{
    EMMC_R1_STATE_IDLE  = 0,
    EMMC_R1_STATE_READY,
    EMMC_R1_STATE_IDENT,
    EMMC_R1_STATE_STBY,
    EMMC_R1_STATE_TRAN,
    EMMC_R1_STATE_DATA,
    EMMC_R1_STATE_RCV,
    EMMC_R1_STATE_PRG,
    EMMC_R1_STATE_DIS,
    EMMC_R1_STATE_BTST,
    EMMC_R1_STATE_SLEP
} EMMC_R1_STATE;

typedef enum{
    ESTATE_BEGIN = 0,
    ESTATE_ISSUE_CMD,
    ESTATE_NON_RESP_CMD,
    ESTATE_RCV_RESP,
    ESTATE_RCV_RESPONSE_BUSY,
    ESTATE_CHECK_RESPONSE_COMPLETE,
    ESTATE_DATA_TRANSFER,
    ESTATE_DATA_TRANSFER_COMPLETE,
    ESTATE_ACCESS_END,
    ESTATE_TRANSFER_ERROR,
    ESTATE_ERROR,
    ESTATE_END
}EMMC_INT_STATE;

/* eMMC boot driver error information */
typedef struct
{
    volatile uint32_t info1;                                /**< SD_INFO1 register value. (hardware dependence) */
    volatile uint32_t info2;                                /**< SD_INFO2 register value. (hardware dependence) */
    volatile uint32_t status1;                              /**< SD_ERR_STS1 register value. (hardware dependence) */
    volatile uint32_t status2;                              /**< SD_ERR_STS2 register value. (hardware dependence) */
    volatile uint32_t dm_info1;                             /**< DM_CM_INFO1 register value. (hardware dependence) */
    volatile uint32_t dm_info2;                             /**< DM_CM_INFO2 register value. (hardware dependence) */
} st_error_info;


/* Command information */
typedef struct
{
    HAL_MEMCARD_COMMAND cmd;                                /**< Command information */
    uint32_t arg;                                           /**< argument */
    HAL_MEMCARD_OPERATION dir;                              /**< direction */
    uint32_t hw;                                            /**< H/W dependence. SD_CMD register value. */
} st_command_info;


/* MMC driver base */
typedef struct
{
    st_error_info error_info;                               /**< error information */
    st_command_info cmd_info;                               /**< command information */

    /* for data transfer */
    uint32_t *buff_address_virtual;                         /**< Dest or Src buff */
    uint32_t *buff_address_physical;                        /**< Dest or Src buff */
    HAL_MEMCARD_DATA_WIDTH bus_width;                       /**< bus width */
    uint32_t trans_size;                                    /**< transfer size for this command */
    uint32_t remain_size;                                   /**< remain size for this command */
    uint32_t response_length;                               /**< response length for this command */

    /* clock */
    uint32_t max_freq;                                      /**< Max frequency (Card Spec)[Hz]. It changes dynamically by CSD and EXT_CSD. */
    uint32_t current_freq;                                  /**< current MMC clock[Hz] (the closest frequency supported by HW) */
    uint32_t set_freq;                                      /**< Frequency to be set. */

    /* state flag */
    uint32_t card_power_enable;                             /**< True : Power ON */
    uint32_t clock_enable;                                  /**< True : Clock ON */
    uint32_t initialize;                                    /**< True : initialize complete. */
    uint32_t mount;                                         /**< True : mount complete. */
    uint32_t selected;                                      /**< True : selected card. */
    HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode;           /**< 0: DMA, 1:PIO */
    EMMC_R1_STATE current_state;                            /**< card state */
    volatile uint32_t during_transfer;                      /**< True : during transfer */
    volatile uint32_t during_dma_transfer;                  /**< True : during transfer (DMA)*/
    volatile uint32_t dma_error_flag;                       /**< True : occurred DMAC error */
    volatile uint32_t force_terminate;                      /**< force terminate flag */
    volatile uint32_t state_machine_blocking;               /**< state machine blocking flag : True or False */

    /* timeout */
    uint32_t data_timeout;                                  /**< read and write data timeout.*/

    /* interrupt */
    volatile uint32_t int_event1;                           /**< interrupt SD_INFO1 Event */
    volatile uint32_t int_event2;                           /**< interrupt SD_INFO2 Event */
    volatile uint32_t dm_event1;                            /**< interrupt DM_CM_INFO1 Event */
    volatile uint32_t dm_event2;                            /**< interrupt DM_CM_INFO2 Event */

    /* response */
    uint32_t *response;                                     /**< pointer to buffer for executing command. */
    uint32_t r1_card_status;                                /**< R1 response data */
    uint32_t r3_ocr;                                        /**< R3 response data */
    uint32_t r4_resp;                                       /**< R4 response data */
    uint32_t r5_resp;                                       /**< R5 response data */

    /* Card registers (4byte align) */
    uint8_t csd_data[EMMC_MAX_CSD_LENGTH];                  /**< CSD */
    uint8_t cid_data[EMMC_MAX_CID_LENGTH];                  /**< CID */
    uint8_t ext_csd_data[EMMC_MAX_EXT_CSD_LENGTH];          /**< EXT_CSD */
    uint8_t response_data[EMMC_MAX_RESPONSE_LENGTH];        /**< other response */

    /* SDHI base address */
    uintptr_t base_address;
} st_mmc_base;

/* ********************** DECLARATION OF EXTERNAL DATA ********************* */

/* ************************** FUNCTION PROTOTYPES ************************** */

/* ********************************* CODE ********************************** */

/* ******************************** END ************************************ */
#endif  /* EMMC_STD_H__ */
/* EMMC_STD_H__ */
