blob: 28328cf89c5a18bcb666cc24d5d7ab2982b4e3db [file] [log] [blame]
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*****************************************************************************
*
* Filename:
* ---------
* msdc.c
*
* Project:
* --------
* Maui_Software
*
* Description:
* ------------
* driver functons for MSDC controller
*
*
* Author:
* -------
* -------
*
*============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
*
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*============================================================================
****************************************************************************/
#include "drv_features.h"
#ifndef DRV_MSDC_OFF
#include "kal_public_api.h" //MSBB change #include "kal_release.h"
#include "md_drv_sap.h"
#include "drv_msgid.h"
#include "kal_general_types.h"
#include "kal_public_defs.h"
#include "kal_public_api.h"
#include "kal_debug.h"
#include "hisr_config.h"
#include "config_hw.h"
#include "init.h"
#include "kal_trace.h"
#include "dcl.h"
#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
#include "kal_public_api.h"
#include "kal_public_api.h" //MSBB change #include "app_ltlcom.h" /* Task message communiction */
#include "intrCtrl.h"
#include "reg_base.h"
#include "drvpdn.h"
#include "drv_features.h"
#include "drv_comm.h"
#include "msdc_reg_adap.h"
#include "drv_hisr.h"
#include "sleepdrv_interface.h"
#include "eint.h"
#if !defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
#include "msdc_api.h"
#include "msdc_def.h"
#include "sd_def.h"
#include "../../../devdrv/iomux/inc/drv_iomux.h"
//! EMB
#include "FTL.h"
#if defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
#include "sdio_sw.h"
#endif
#if defined(__MSDC_MS__)
#include "ms_def.h"
#elif defined(__MSDC_MSPRO__)
#include "mspro_def.h"
#endif
#include "upll_ctrl.h"
//#include "gpio_sw.h"
#include "drv_trc.h"
#if defined(__AUDIO_DSP_LOWPOWER__)
#include "audlp_exp.h"
#endif
#ifdef DRV_LSD
#include "msdc_lsd.h"
#endif
#ifdef __CLKG_DEFINE__
#ifdef DRVPDN_CON1
#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
#else
#define DRVPDN_CON1 CG_CON1
#endif
#ifdef DRVPDN_CON1_SIM
#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
#else
#define DRVPDN_CON1_SIM CG_CON1_SIM
#endif
#ifndef MSDC_TEST_MSDC2_FROM_MSDC1_CODE
#ifdef DRVPDN_CON1_MSDC
#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
#else
#define DRVPDN_CON1_MSDC CG_CON1_MSDC
#endif
#ifdef DRVPDN_CON1_CLR
#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
#else
#define DRVPDN_CON1_CLR CG_CLR1
#endif
#ifdef DRVPDN_CON1_SET
#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
#else
#define DRVPDN_CON1_SET CG_SET1
#endif
#else /*when MSDC_TEST_MSDC2_FROM_MSDC1_CODE is defined, we direct CON1 related macro to CON0 related*/
#ifdef DRVPDN_CON1_MSDC
#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
#else
#define DRVPDN_CON1_MSDC CG_CON0_MSDC2
#endif
#ifdef DRVPDN_CON1_CLR
#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
#else
#define DRVPDN_CON1_CLR CG_CLR0
#endif
#ifdef DRVPDN_CON1_SET
#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
#else
#define DRVPDN_CON1_SET CG_SET0
#endif
#endif//MSDC_TEST_MSDC2_FROM_MSDC1_CODE
#endif
/*
#if !(defined __MSDC_NOT_SUPPORT_HOT_PLUG__)
#if defined(MT6218B_FN) || defined(MT6219_EV) ||defined(MT6217)||defined(MT6227)||defined(MT6226)||defined(MT6226M)\
|| defined(MT6225)
#define USE_INT26_CARD_DETECTION
#endif
#endif
*/
#if defined (WISDOM35B_DEMO_BB)
extern const char gpio_SD_det_pin;
#endif
// global variable
MSDC_HANDLE MSDC_Blk[SD_NUM];
#if (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__)|| defined(__MSDC_MSPRO__)) || defined(__MSDC_SD_SDIO__)
MSDC_HANDLE *gMSDC_Handle = &(MSDC_Blk[0]);
#if defined(__UBL__) && defined(__EMMC_BOOTING__)
__attribute__ ((zero_init, section ("EXT_UN_INIT_ZI")))kal_uint32 MSDC_Sector[128];
__attribute__ ((zero_init, section ("EXT_UN_INIT_ZI")))kal_uint32 MSDC_eCSD[128];
#ifdef MSDC_CACHED_SUPPORT
__attribute__ ((zero_init, section ("EXT_UN_INIT_ZI")))kal_uint32 msdc_uncachedBuf[MSDC_UNCACHED_BUF_SIZE / 4];
#endif
#else
__attribute__ ((zero_init, section ("NONCACHEDZI")))kal_uint32 MSDC_Sector[128];
__attribute__ ((zero_init, section ("NONCACHEDZI")))kal_uint32 MSDC_eCSD[128];
#ifdef MSDC_CACHED_SUPPORT
__attribute__ ((zero_init, section ("NONCACHEDZI")))kal_uint32 msdc_uncachedBuf[MSDC_UNCACHED_BUF_SIZE / 4];
#endif
#endif
//Light 120907
#define MSDC_DMA_BURSTLEN_LIMIT 0xFFFFFFFF//4294966784 //32bit
//#define MSDC_DMA_BURSTLEN_LIMIT 65024
kal_bool MSDC_useDMA4ByteBurst = KAL_FALSE;
/* Debug log */
kal_uint32 MSDC_DebugLevel;
/* IO configurations */
static struct msdc_cust msdc_cap = {
0, /* host clock source */
1, /* command latch edge */
1, /* read data latch edge */
1, /* write data latch edge */
{6, 6, 0, 0, 1, 0, 1},
{4, 4, 0, 0, 1, 0, 1},
{4, 4, 0, 0, 1, 0, 1},
8, /* data pins */
0, /* data address offset */
/* hardware capability flags */
0,
};
#ifdef __TST_WRITE_TO_FILE__
/*error recording: add this additional global variable to use when in error recording*/
MSDC_HANDLE MSDC_ErrorRecordingBlk;
#endif
#if defined(DRV_MSDC_SHARE_BY_SWITCH)
sd_select_enum current_card; // active card
#if !defined(__CUST_NEW__)
extern kal_char MSDC_GetLDO_GPIO(void);
extern kal_char MSDC_GetSwitch_GPIO(void);
extern kal_char MSDC_GetEXTLDO_GPIO(void);
extern kal_char MSDC_GetSwitchDirection(void);
kal_char gpio_simplug_ldo_switch;
kal_char gpio_ext_sd_ldo_switch;
kal_char gpio_sim_msdc_switch;
#endif
#endif
#if !defined(DRV_LSD) && defined(__DRV_DBG_MEMORY_TRACE_SUPPORT__) && !defined(__UBL__)
msdc_debugMessage msdc_msgArray[MSDC_DBG_ARRAY_SIZE];
kal_uint32 msdc_msdIndex;
#endif
#define MSDC_EINT_NUM MSDC_EINT_NO
// system control blocks
// function predeclaration
void MSDC_DMAInit(void);
void MSDC_INT_Init(void);
void MSDC_DMA_Callback(void);
void MSDC_EINT_Handler(void);
void MSDC_turnOnVMC(kal_bool turnOnLdo);
#ifdef R1B_INTERRUPT_MODE
static void MSDC_R1B_Init();
#endif
extern void GPIO_ModeSetup(kal_uint16 pin, kal_uint16 conf_dada);
extern kal_bool INT_USBBoot(void);
extern kal_int8 MSDC_GetDLTFromOPCLK(kal_uint32 opClk, kal_uint8 *setRED);
extern void SD_Sleep4Wait(kal_int32 sleep_tick);
extern void msdc_tune_init(void);
#ifdef __CARD_DOWNLOAD__
extern kal_bool MSDC_QueryIsPowerControllable(void);
extern void MSDC_SetPower(kal_bool enable);
#endif
#if !defined(_MSDC_INTERNAL_CD_INT_PIN_)
#if defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
#error "__MSDC_NOT_SUPPORT_HOT_PLUG__ shouldn't be defined."
#endif
extern const unsigned char MSDC_EINT_NO;
static kal_uint32 MSDC_debounceTime;
static kal_bool cardDetectionEINTPolarity;
#endif
#if defined(__UBL__) || defined(__FUE__)
kal_bool MSDC_START_TIMER(kal_uint16 x)
{
gMSDC_Handle->is_timeout = KAL_FALSE;
}
#else// defined(__UBL__) || defined(__FUE__)
kal_bool MSDC_START_TIMER(kal_uint16 x)
{
//DCL_HANDLE gpt_handle;
DCL_STATUS status;
SGPT_CTRL_START_T start;
#if defined(MSDC_DEBUG_INFO)
strcpy(gMSDC_Handle->msdc_fname, __FILE__);
gMSDC_Handle->msdc_lines = __LINE__;
#endif
gMSDC_Handle->is_timeout = KAL_FALSE;
start.u2Tick = x;
start.pfCallback = MSDC_TimeOutHandler;
start.vPara = NULL;
//gpt_handle= module |MSDC_GPT_CB_MAGIC_NUM;
status = DclSGPT_Control(MSDC_Blk[0].gpt_handle, SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start);
//dbg_print("start timer++++++++%d+++++\r\n",drv_get_current_time());
if (STATUS_OK == status)
return KAL_TRUE;
else
return KAL_FALSE;
}
#endif// defined(__UBL__) || defined(__FUE__)
#if defined(__UBL__) || defined(__FUE__)
kal_bool MSDC_STOP_TIMER()
{
return KAL_TRUE;
}
#else// defined(__UBL__) || defined(__FUE__)
kal_bool MSDC_STOP_TIMER()
{
//MSDC_GPTI_StopItem(gMSDC_Handle->gpt_handle);
DclSGPT_Control(MSDC_Blk[0].gpt_handle, SGPT_CMD_STOP, 0);
if (gMSDC_Handle->is_timeout ||!gMSDC_Handle->mIsPresent)
{
kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
}
//dbg_print("stop timer +++++++%d++++++++\r\n",drv_get_current_time());
return KAL_TRUE;
}
#endif// defined(__UBL__) || defined(__FUE__)
#if !defined(__FUE__) && !defined(__UBL__)
void MSDC_GPTI_BusyWait(kal_uint16 len)
{
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
}
kal_uint8 MSDC_GPTI_GetHandle(DCL_HANDLE *handle)
{
//DCL_HANDLE gpt_handle;
*handle = DclSGPT_Open(DCL_GPT_CB, 0);
//*handle = 0xFF & gpt_handle;
return KAL_TRUE;
}
#endif//!defined(__FUE__) && !defined(__UBL__)
/*************************************************************************
* FUNCTION
* MSDC_SetClock
*
* DESCRIPTION
*
* PARAMETERS
* clock: the desired operating clock rate in the unit of kHz
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_uint32 MSDC_SetClock(kal_uint32 bus_clock,kal_bool ddr_mode)
{
kal_uint32 msdc_clock,op_clock=0;
kal_uint32 div,mode;
if (!gMSDC_Handle->msdc_clock)
{
/*didn't set source clock*/
MSDC_ERR("[MSDC][%s %d]set clock before set source clock\r\n",__FUNCTION__,__LINE__);
return MSDC_ERROR;
}
msdc_clock=gMSDC_Handle->msdc_clock;
if (!(bus_clock))
{
MSDC_RESET();
MSDC_ENABLE_CARD_CLOCK(KAL_TRUE);
MSDC_ERR("[MSDC][%s %d]can't set bus clock to %d\r\n",__FUNCTION__,__LINE__,bus_clock);
return MSDC_ERROR;
}
/* Check the MAX bus clock which could be supportted by driver */
if (bus_clock > gMSDC_Handle->op_clock_max)
bus_clock = gMSDC_Handle->op_clock_max;
/*need disable irq*/
MSDC_ENABLE_CARD_CLOCK(KAL_FALSE);
if (ddr_mode){
mode=USE_DDR_MODE;
if (bus_clock>=(msdc_clock >> 2)){
div=0;
op_clock=msdc_clock >> 2;
}
else
{
bus_clock=bus_clock << 1;
div=(msdc_clock+((bus_clock << 2)-1))/(bus_clock << 2);
op_clock=(msdc_clock>>2)/div;
op_clock=op_clock>>1;
}
}
else
{
if (bus_clock >=msdc_clock)
{
//dbg_print("entry bus_clock==msdc_clock\r\n");
mode =USE_MSDC_SRC_CK;
div=0;
op_clock=msdc_clock;
}
else
{
mode =USE_CLOCK_DIV;
if (bus_clock >= (msdc_clock >> 1))
{
div=0;
op_clock=msdc_clock>>1;
//dbg_print("entry bus_clock >= (msdc_clock>>1),op_clock=%d\r\n",op_clock);
} else {
div=(msdc_clock+((bus_clock << 2)-1))/(bus_clock << 2);
op_clock=(msdc_clock >> 2)/div;
//dbg_print("entry bus_clock <(msdc_clock>>1),bus_clock=%d ,op_clock=%d,msdc_clock=%d\r\n",bus_clock,op_clock,msdc_clock);
}
}
}
gMSDC_Handle->op_clock=op_clock;
gMSDC_Handle->msdc_clock=msdc_clock;
//dbg_print("op_clock=%d ,msdc_clock=%d,div=%x\r\n",op_clock,msdc_clock,div);
BitFieldWrite32((kal_uint32 *)MSDC_CFG, mode, MSDC_CFG_CKMOD);
BitFieldWrite32((kal_uint32 *)MSDC_CFG,div,MSDC_CFG_CKDIV);
if (MSDC_TIMEOUT_WAIT((MSDC_Reg32(MSDC_CFG)&MSDC_CFG_CKSTB),500))
{
MSDC_ERR("[MSDC][%s %d]wait clock stable 500ms,then timeout \r\n",__FUNCTION__,__LINE__);
return MSDC_ERROR;
}
//dbg_print("MSDC_CFG=%x\r\n",MSDC_Reg32(MSDC_CFG));
/*open irq*/
MSDC_CRIT("[MSDC][%s %d] SET_CLK(%dkHz): SCLK(%dkHz) MODE(%d) DDR(%d) DIV(%d)\r\n",
__FUNCTION__,__LINE__, bus_clock / 1000, op_clock / 1000, mode, ddr_mode, div);
MSDC_ENABLE_CARD_CLOCK(KAL_TRUE);
return MSDC_OK;
}
kal_uint32 uffs(kal_uint32 x)
{
kal_uint32 r=1;
if (!x)
{
return 0 ;
}
if (!(x&0xffff))
{
x>>=16;
r+=16;
}
if (!(x&0xff))
{
x>>=8;
r+=8;
}
if (!(x&0xf))
{
x>>=4;
r+=4;
}
if (!(x&0x3))
{
x>>=2;
r+=2;
}
if (!(x&0x1))
{
x>>=1;
r+=1;
}
return r;
}
void msdc_sleep(kal_uint32 ticks)
{
if ((kal_query_systemInit() == KAL_TRUE)
#ifdef __TST_WRITE_TO_FILE__ /*error recording: considering error recording additionally*/
|| (KAL_TRUE == INT_QueryExceptionStatus())
#endif
#ifndef __MTK_TARGET__
|| KAL_TRUE == FTL_isPollingMode()
#endif
)
{
MSDC_GPTI_BusyWait(ticks*5);
}
else
{
kal_sleep_task(ticks);
}
}
/*************************************************************************
* FUNCTION
* MSDC_SetClockSource
*
* DESCRIPTION
*
* PARAMETERS
* type: the desired operating clock source
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
#if (CHIP_VER == 0)
void MSDC_SetClockSource(T_MSDC_CLK_TYPE type)
{
kal_uint32 orig_val;
// 3'b000: 26MHz
// 3'b001: 40MHz
// 3'b010: 50MHz
// 3'b011: 60MHz
// 3'b100: 69MHz
// 3'b101: 80MHz
// 3'b110: 96MHz
// 3'b111: 100MHz
#define MSDC_SOURCE_SEL_ADDR (0xBF814004)
orig_val=MSDC_Reg32(MSDC_SOURCE_SEL_ADDR);
orig_val=orig_val&(~0x7);
switch (type)
{
case SRC_26M:
MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_26M);
gMSDC_Handle->msdc_clock=26000000;
gMSDC_Handle->op_clock_max = 13000000;
break;
case SRC_40M:
MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_40M);
gMSDC_Handle->msdc_clock=40000000;
gMSDC_Handle->op_clock_max = 20000000;
break;
case SRC_50M:
MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_50M);
gMSDC_Handle->msdc_clock=50000000;
gMSDC_Handle->msdc_clock=35000000;
gMSDC_Handle->op_clock_max = 17000000;
break;
case SRC_60M:
MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_60M);
gMSDC_Handle->msdc_clock=60000000;
gMSDC_Handle->op_clock_max = 30000000;
break;
case SRC_69M:
MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_69M);
gMSDC_Handle->msdc_clock=69000000;
gMSDC_Handle->op_clock_max = 35000000;
break;
case SRC_80M:
MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_80M);
gMSDC_Handle->msdc_clock=80000000;
gMSDC_Handle->op_clock_max = 40000000;
break;
case SRC_96M:
MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_96M);
gMSDC_Handle->msdc_clock=96000000;
gMSDC_Handle->op_clock_max = 48000000;
break;
case SRC_100M:
MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_100M);
gMSDC_Handle->msdc_clock=100000000;
gMSDC_Handle->op_clock_max = 50000000;
break;
default:
MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_26M);
gMSDC_Handle->msdc_clock=26000000;
MSDC_ERR("[MSDC][%s %d]unknow source CLK %d\r\n",__FUNCTION__,__LINE__,type);
break;
}
}
#elif (CHIP_VER == 1)
#define MSDC_OP_SCLK (200000000)
#define MSDC_MAX_SCLK (200000000)
void MSDC_SetClockSource(T_MSDC_CLK_TYPE type)
{
gMSDC_Handle->msdc_clock = MSDC_OP_SCLK;
gMSDC_Handle->op_clock_max = MSDC_MAX_SCLK;
}
#endif
/*************************************************************************
* FUNCTION
* MSDC_Check_Card_Present
*
* DESCRIPTION
* c
*
* PARAMETERS
* ON: turn on power saving or not
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
kal_bool MSDC_Check_Card_Present(void)
{
#if !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
return gMSDC_Handle->mIsPresent;
#else
return KAL_TRUE;
#endif
}
/*************************************************************************
* FUNCTION
* MSDC_PDNControl
*
* DESCRIPTION
* Enable power saving or not.
*
* PARAMETERS
* ON: turn on power saving or not
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
#define MSDC_PDN_EN
void MSDC_PDNControl(kal_bool ON)
{
if (ON) {
#if !defined(ATEST_DRV_ENABLE)
#if defined(MSDC_PDN_EN)
PDN_SET(PDN_MSDC0);
#endif
SleepDrv_SleepEnable(gMSDC_Handle->msdc_sm_hdl);
#endif
}
else {
#if !defined(ATEST_DRV_ENABLE)
#if defined(MSDC_PDN_EN)
PDN_CLR(PDN_MSDC0);
#endif
SleepDrv_SleepDisable(gMSDC_Handle->msdc_sm_hdl);
#endif
}
}
/*************************************************************************
* FUNCTION
* MSDC_TimeOutHandler
*
* DESCRIPTION
* Callback function of gpt timer, and launched while MSDC busy for a while
*
* PARAMETERS
*
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_TimeOutHandler(void *parameter)
{
gMSDC_Handle->is_timeout=KAL_TRUE;
kal_set_eg_events(gMSDC_Handle->MSDC_Events,
EVENT_DMA_DONE|EVENT_XFER_DONE|EVENT_CMD_DONE,KAL_OR);
MSDC_ERR("[MSDC][%s %d] Enter timeout handler \r\n",__FUNCTION__,__LINE__);
}
/*************************************************************************
* FUNCTION
* MSDC_GetCardStatus
*
* DESCRIPTION
* Check currently card is present or not.
*
* PARAMETERS
*
*
* RETURNS
*
* GLOBALS AFFECTED
* msdc_eint_state
*
*
*************************************************************************/
int MSDC_GetCardStatus(void * DriveData, int AckType)
{
return 0;
}
/*************************************************************************
* FUNCTION
* MSDC_SendCardInd
*
* DESCRIPTION
* Send card indication to the specified module.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_SendCardInd(module_type dest_id, sd_select_enum sel, kal_uint32 msg_id)
{
}
/*************************************************************************
* FUNCTION
* MSDC_GetMediaChanged
*
* DESCRIPTION
* Check if the media is changed, and clear the status after function call
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
kal_bool MSDC_GetMediaChanged(sd_select_enum sel)
{
kal_bool ret;
ENTER_CRITICAL();
ret = (MSDC_Blk[sel].mIsChanged ) ? (KAL_TRUE) : (KAL_FALSE);
MSDC_Blk[sel].mIsChanged = KAL_FALSE;
EXIT_CRITICAL();
return ret;
}
/*************************************************************************
* FUNCTION
* MSDC_InvertN
*
* DESCRIPTION
* Invert the order of bytes eg,
* src: 0x01 0x02, len: 2 => dest: 0x02 0x01
*
* PARAMETERS
* 1. dest: used for store inverted result
* 2. src: source for inverting
* 3. len: bytes for inverting
*
* RETURNS
*
* GLOBALS AFFECTED
*
* NOTE
* 1. make sure dest has the same size with src.
*************************************************************************/
void MSDC_InvertN(kal_uint8 *dest, kal_uint8 *src, kal_uint8 len)
{
int i;
for (i = 0; i < len; i++)
*(dest + len - 1 - i) = *(src + i);
}
/*************************************************************************
* FUNCTION
* MSDC_Config_INS_WP
*
* DESCRIPTION
* Configure the pull up or pull down status for INS and WP pin
*
* PARAMETERS
* 1. ins: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
* 2. wp: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
*
* RETURNS
*
* GLOBALS AFFECTED
*
* NOTE
* 1. MT6219 can not be configured to PULL up or down. They are all pulled up by IO.
* 2. MT6218B and MT6217, WP is configured with data lines.
*************************************************************************/
void MSDC_Config_INS_WP(msdc_ioctrl_enum ins, msdc_ioctrl_enum wp)
{
}
void MSDC_InitializeSwitchGpio()
{
#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
DCL_HANDLE handle;
#if !defined(__CUST_NEW__)
GPIO_LDO_SWITCH = MSDC_GetLDO_GPIO();
GPIO_EXT_SD_LDO_SWITCH = MSDC_GetEXTLDO_GPIO();
GPIO_SIM_MSDC_SWITCH = MSDC_GetSwitch_GPIO();
#endif
//GPIO_ModeSetup(GPIO_SIM_MSDC_SWITCH, 0); // gpio mode (replaced by DCL)
handle = DclGPIO_Open(DCL_GPIO, GPIO_SIM_MSDC_SWITCH);
DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
DclGPIO_Close(handle);
//GPIO_InitIO(OUTPUT, GPIO_SIM_MSDC_SWITCH); // replaced by DCL
handle = DclGPIO_Open(DCL_GPIO, GPIO_SIM_MSDC_SWITCH);
DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
DclGPIO_Close(handle);
/*bewlow comes after JRD SIM+ issue on 2007_03_08, use custom setting instead of fix value*/
//GPIO_WriteIO(MSDC_GetSwitchDirection(), GPIO_SIM_MSDC_SWITCH); // replaced by DCL
handle = DclGPIO_Open(DCL_GPIO, GPIO_SIM_MSDC_SWITCH);
if (0 == MSDC_GetSwitchDirection())
DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
else if (1 == MSDC_GetSwitchDirection())
DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
else
{
DclGPIO_Close(handle);
ASSERT(0);
}
DclGPIO_Close(handle);
/*end of changes of JRD SIM+ issue on 2007_03_08*/
#endif
}
#if !defined(_MSDC_INTERNAL_CD_INT_PIN_)
#if defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
kal_bool EINT_DefaultPolarity = KAL_FALSE;
#else
kal_bool EINT_DefaultPolarity = KAL_FALSE;
#endif
#endif
void MSDC_ConfigPin(kal_uint32 pullmode)
{
/*
* Note that the CLK signal is a output signal,
* and it should be kept to the default value.
* that is, PULL DOWN
*/
switch (pullmode)
{
case MSDC_PIN_PULL_UP:
/* For CMD pin */
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU_DUAL_IO, 1);
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD_DUAL_IO, 0);
/* For DATA pin */
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU_DUAL_IO, 1);
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD_DUAL_IO, 0);
break;
case MSDC_PIN_PULL_DOWN:
/* For CMD pin */
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU_DUAL_IO, 0);
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD_DUAL_IO, 1);
/* For DATA pin */
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU_DUAL_IO, 0);
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD_DUAL_IO, 1);
break;
case MSDC_PIN_PULL_NONE:
default:
/* For CMD pin */
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU_DUAL_IO, 0);
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD_DUAL_IO, 0);
/* For DATA pin */
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU_DUAL_IO, 0);
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD_DUAL_IO, 0);
break;
}
}
/*************************************************************************
* FUNCTION
* MSDC_SetHostPower
*
* DESCRIPTION
* enable or disable the power of host
*
* PARAMETERS*
* on: KAL_TURE enable the power, KAL_FALSE disable the power
*
* RETURNS
*
* KAL_FALSE: fail to set the power
* KAL_TURE: success to set the power
*
* GLOBALS AFFECTED
* gMSDC_Handle
*
*************************************************************************/
kal_bool MSDC_SetHostPower(kal_bool on)
{
kal_bool ret = KAL_TRUE;
return ret;
}
#if (CHIP_VER == 0)
/*************************************************************************
* FUNCTION
* MSDC_SetVddPower
*
* DESCRIPTION
* enable or disable the power of host
*
* PARAMETERS*
* on: KAL_TURE enable the power, KAL_FALSE disable the power
* volt: the voltage of vdd 3300 mean 3.3v
* RETURNS
*
* KAL_FALSE: fail to set the power
* KAL_TURE: success to set the power
*
* GLOBALS AFFECTED
* gMSDC_Handle
*
*************************************************************************/
kal_bool MSDC_SetVddPower(kal_bool on,kal_uint32 volt)
{
kal_bool ret =KAL_TRUE;
if (on)
{
if (volt == 3300)
{
MSDC_ConfigPin(MSDC_PIN_PULL_UP);
}
else
{
ret = KAL_FALSE;
}
}
else
{
MSDC_ConfigPin(MSDC_PIN_PULL_DOWN);
}
return ret;
}
/*************************************************************************
* FUNCTION
* MSDC_SetSignalPower
*
* DESCRIPTION
* enable or disable the power of host
*
* PARAMETERS*
* on: KAL_TURE enable the power, KAL_FALSE disable the power
* volt: the voltage of signal , 3300 mean 3.3v ,1800 mean 1.8v
* RETURNS
*
* KAL_FALSE: fail to set the power
* KAL_TURE: success to set the power
*
* GLOBALS AFFECTED
* gMSDC_Handle
*
*************************************************************************/
/*
CARD_PWR 1 LEVEL_PWR33 0 1.8v
CARD_PWR 1 LEVEL_PWR33 1 3.3v
CARD_PWR0 0v
*/
#define MSDC_CARD_PWR 26
#define MSDC_LEVEL_PWR33 27
kal_bool MSDC_SetSignalPower(kal_bool on,kal_uint32 volt)
{
DCL_HANDLE handle;
kal_bool ret =KAL_TRUE;
if (on)
{
handle = DclGPIO_Open(DCL_GPIO, MSDC_CARD_PWR);
DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
//DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
DclGPIO_Close(handle);
if (volt == 3300)
{
handle = DclGPIO_Open(DCL_GPIO, MSDC_LEVEL_PWR33);
DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
//DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
DclGPIO_Close(handle);
MSDC_CRIT("[MSDC][%s %d]set signal power to 3.3v\r\n",__FUNCTION__,__LINE__);
gMSDC_Handle->signal_volt=3300;
}
else if (volt ==1800)
{
handle = DclGPIO_Open(DCL_GPIO,MSDC_LEVEL_PWR33);
DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
//DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
DclGPIO_Close(handle);
MSDC_CRIT("[MSDC][%s %d]set signal power to 1.8v\r\n",__FUNCTION__,__LINE__);
gMSDC_Handle->signal_volt=1800;
}
else
{
MSDC_ERR("[MSDC][%s %d]unknow signal power %d v\r\n",__FUNCTION__,__LINE__,volt);
ret = KAL_FALSE;
}
}
else
{
/*set signal volt to 0v*/
handle = DclGPIO_Open(DCL_GPIO, MSDC_CARD_PWR);
DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
//DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
DclGPIO_Close(handle);
MSDC_CRIT("[MSDC][%s %d]set signal power to 0v\r\n",__FUNCTION__,__LINE__);
gMSDC_Handle->signal_volt=0;
}
return ret;
}
#elif (CHIP_VER == 1)
#define LDO_VMC 0
#define LDO_VMCH 1
#define LDO_VIO18_PMU 2
static kal_uint32 g_msdc0_io = PMU_VOLT_03_300000_V;
static kal_uint32 g_msdc0_card = PMU_VOLT_03_300000_V;
static kal_uint32 hwPowerOn(kal_uint32 powerID, PMU_VOLTAGE_ENUM powerVolt)
{
PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
PMU_CTRL_LDO_BUCK_SET_VOLTAGE pmu_volsel;
DCL_HANDLE handle;
/* Open PMU handle */
handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
switch(powerID) {
case LDO_VMC:
/* Set enable control */
pmu_en.mod = VMC;
pmu_en.enable = 1;
/* Set voltage */
pmu_volsel.mod = VMC;
pmu_volsel.voltage = powerVolt;
DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
break;
case LDO_VMCH:
/* Set enable control */
pmu_en.mod = VMCH;
pmu_en.enable = 1;
/* Set voltage */
pmu_volsel.mod = VMCH;
pmu_volsel.voltage = powerVolt;
DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
break;
default:
break;
}
/* Close PMU handle */
DclPMU_Close(handle);
return 1;
}
static kal_uint32 hwPowerDown(kal_uint32 powerID)
{
PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
DCL_HANDLE handle;
/* Open PMU handle */
handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
switch(powerID) {
case LDO_VMC:
/* Set enable control */
pmu_en.mod = VMC;
pmu_en.enable = 0;
DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
break;
case LDO_VMCH:
/* Set enable control */
pmu_en.mod = VMCH;
pmu_en.enable = 0;
DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
break;
default:
break;
}
/* Close PMU handle */
DclPMU_Close(handle);
return 1;
}
static kal_uint32 msdc_ldo_power(kal_uint32 on, kal_uint8 powerId,
PMU_VOLTAGE_ENUM powerVolt, kal_uint32 *status)
{
if (on) { // want to power on
if (*status == 0) { // can power on
MSDC_CRIT("msdc LDO<%s> power on<%d>\r\n",
powerId ? "VMCH" : "VMC", powerVolt);
hwPowerOn(powerId, powerVolt);
*status = powerVolt;
} else if (*status == powerVolt) {
MSDC_CRIT("msdc LDO<%s><%d> power on again!\r\n",
powerId ? "VMCH" : "VMC", powerVolt);
} else { // for sd3.0 later
MSDC_CRIT("msdc LDO<%s> change<%d> to <%d>\r\n",
powerId ? "VMCH" : "VMC", *status, powerVolt);
hwPowerDown(powerId);
hwPowerOn(powerId, powerVolt);
*status = powerVolt;
}
} else { // want to power off
if (*status != 0) { // has been powerred on
MSDC_CRIT("msdc LDO<%s> power off\r\n", powerId ? "VMCH" : "VMC");
hwPowerDown(powerId);
*status = 0;
} else {
MSDC_CRIT("LDO<%s> not power on\r\n", powerId ? "VMCH" : "VMC");
}
}
return 0;
}
void msdc_set_smt(kal_bool clk, kal_bool cmd, kal_bool dat)
{
clk &= 0xF;
cmd &= 0xF;
dat &= 0xF;
/* For CLK pin */
MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSMT, clk);
/* For CMD pin */
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSMT, cmd);
/* For DATA pin */
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSMT, dat);
}
void msdc_set_slew_rate(int clk,int cmd, int dat)
{
clk &= 0x1;
cmd &= 0x1;
dat &= 0x1;
/* For CLK pin */
MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSR, clk);
/* For CMD pin */
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSR, cmd);
/* For DATA pin */
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSR, dat);
}
void msdc_set_rdsel(kal_bool clk, kal_bool cmd, kal_bool dat)
{
clk &= 0xF;
cmd &= 0xF;
dat &= 0xF;
/* For CLK pin */
MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKRDSEL, clk);
/* For CMD pin */
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDRDSEL, cmd);
/* For DATA pin */
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATRDSEL, dat);
}
void msdc_set_tdsel(kal_bool clk, kal_bool cmd, kal_bool dat)
{
clk &= 0xF;
cmd &= 0xF;
dat &= 0xF;
/* For CLK pin */
MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKTDSEL, clk);
/* For CMD pin */
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDTDSEL, cmd);
/* For DATA pin */
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATTDSEL, dat);
}
void msdc_set_driving(struct msdc_cust *hw, kal_bool sd_18)
{
if (sd_18) {
/* For CLK pin */
MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRV, hw->io_clk.io_drv_18);
/* For CMD pin */
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRV, hw->io_cmd.io_drv_18);
/* For DATA pin */
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRV, hw->io_dat.io_drv_18);
} else {
/* For CLK pin */
MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRV, hw->io_clk.io_drv_33);
/* For CMD pin */
MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRV, hw->io_cmd.io_drv_33);
/* For DATA pin */
MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRV, hw->io_dat.io_drv_33);
}
}
int msdc_io_init()
{
struct msdc_cust *pmsdc_cust = NULL;
pmsdc_cust = &msdc_cap;
if (!pmsdc_cust) {
MSDC_ERR("<%s> : Invalid host ID!\r\n", __FUNCTION__);
goto exit;
}
/* RDSEL Init */
msdc_set_rdsel(pmsdc_cust->io_clk.rdsel, pmsdc_cust->io_cmd.rdsel,
pmsdc_cust->io_dat.rdsel);
/* TDSEL Init */
msdc_set_tdsel(pmsdc_cust->io_clk.tdsel, pmsdc_cust->io_cmd.tdsel,
pmsdc_cust->io_dat.tdsel);
/* SMTen Init */
msdc_set_smt(pmsdc_cust->io_clk.smten, pmsdc_cust->io_cmd.smten,
pmsdc_cust->io_dat.smten);
/* Slew Rate Init */
msdc_set_slew_rate(pmsdc_cust->io_clk.slew, pmsdc_cust->io_cmd.slew,
pmsdc_cust->io_dat.slew);
/* IO driving Init */
msdc_set_driving(pmsdc_cust, 0);
exit:
return 1;
}
void msdc_pin_init()
{
/* Pin config for MSDC0 */
#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
/* Set to MSDC function(INS and WP) */
IOMUX_set_module_func(0, sel_msdc0p_0);
#else
/* Set GPIO/EINT function, both for INS and WP */
IOMUX_set_module_func(4, sel_msdc0p_0);
#ifdef ATEST_DRV_MSDC
GPIO_init();
EINT_Setting_Init();
#endif
#endif
IOMUX_set_module_func(0, sel_msdc0p_1);
IOMUX_set_module_func(0, sel_msdc0p_2);
return;
}
kal_bool MSDC_SetVddPower(kal_bool on, kal_uint32 volt)
{
kal_bool ret =KAL_TRUE;
if (on)
MSDC_ConfigPin(MSDC_PIN_PULL_UP);
if (volt == 3300)
{
msdc_ldo_power(on, LDO_VMCH, PMU_VOLT_03_300000_V, &g_msdc0_card);
}
else
{
MSDC_ERR("[MSDC][%s %d]unknow signal power %d v\r\n",
__FUNCTION__, __LINE__, volt);
ret = KAL_FALSE;
}
if (!on)
MSDC_ConfigPin(MSDC_PIN_PULL_UP);
return ret;
}
kal_bool MSDC_SetSignalPower(kal_bool on,kal_uint32 volt)
{
kal_bool ret =KAL_TRUE;
if (volt == 3300)
{
msdc_ldo_power(on, LDO_VMC, PMU_VOLT_03_300000_V, &g_msdc0_io);
msdc_set_driving(&msdc_cap, 0);
}
else if (volt ==1800)
{
msdc_ldo_power(on, LDO_VMC, PMU_VOLT_01_800000_V, &g_msdc0_io);
msdc_set_driving(&msdc_cap, 1);
}
else
{
MSDC_ERR("[MSDC][%s %d]unknow signal power %d v\r\n",
__FUNCTION__, __LINE__, volt);
ret = KAL_FALSE;
}
return ret;
}
#endif
/*************************************************************************
* FUNCTION
* MSDC_SetAllPower
*
* DESCRIPTION
* enable or disable the power of host\Vdd\signal
*
* PARAMETERS*
*
* RETURNS
*
* KAL_FALSE: fail to set the power
* KAL_TURE: success to set the power
*
* GLOBALS AFFECTED
* gMSDC_Handle
*
*************************************************************************/
kal_bool MSDC_SetAllPower(kal_bool on)
{
kal_bool ret=KAL_TRUE;
if (on)
{
MSDC_SetHostPower(on);
MSDC_SetVddPower(on,gMSDC_Handle->vdd_volt);
MSDC_SetSignalPower(on,gMSDC_Handle->signal_volt);
}
else
{
MSDC_SetSignalPower(on,gMSDC_Handle->signal_volt);
MSDC_SetVddPower(on,gMSDC_Handle->vdd_volt);
MSDC_SetHostPower(on);
}
return ret;
}
void power_cycle(kal_uint32 interval_ticks)
{
MSDC_SetVddPower(0,gMSDC_Handle->vdd_volt);
msdc_sleep(interval_ticks);
MSDC_SetVddPower(1,gMSDC_Handle->vdd_volt);
}
/*************************************************************************
* FUNCTION
* MSDC_SetBusWidth
*
* DESCRIPTION
* set the bus width to 1 ,4 8
*
* PARAMETERS*
* bus_width : set to 1 ,4 ,8
* RETURNS
*
* GLOBALS AFFECTED
* gMSDC_Handle
*
*************************************************************************/
void MSDC_SetBusWidth(SD_BITWIDTH bus_width)
{
kal_uint32 val;
val=MSDC_Reg32(SDC_CFG)&(~SDC_CFG_BUSWIDTH);
switch(bus_width)
{
default:
case BIT_1W:
val |=(MSDC_BUS_1BITS << 16);
gMSDC_Handle->bus_width=1;
break;
case BIT_4W:
val |=(MSDC_BUS_4BITS <<16);
gMSDC_Handle->bus_width=4;
break;
case BIT_8W:
val |=(MSDC_BUS_8BITS<<16);
gMSDC_Handle->bus_width=8;
break;
}
MSDC_WriteReg32(SDC_CFG,val);
MSDC_CRIT("[MSDC][%s %d]Set to %d-bit bus width\r\n", __FUNCTION__,
__LINE__, gMSDC_Handle->bus_width);
}
void MSDC_FatalErrorHandle()
{
/*reset msdc*/
MSDC_RESET();
/*stop dma*/
MSDC_STOP_DMA();
/*clear fifo*/
MSDC_CLR_FIFO_EX();
/*clear ints*/
MSDC_CLR_INT();
/**/
}
kal_uint32 MSDC_PollInts(kal_uint32 int_mask,kal_uint32 timeout_ms)
{
kal_uint32 intsts;
if (!MSDC_TIMEOUT_WAIT((MSDC_Reg32(MSDC_INT)&int_mask),timeout_ms))
{
intsts=MSDC_Reg32(MSDC_INT);
MSDC_WriteReg32(MSDC_INT,intsts&int_mask);
return intsts&int_mask;
}
MSDC_ERR("[MSDC][%s %d]poll INT %d, SW timeout\r\n",__FUNCTION__,__LINE__,timeout_ms);
return 0;
}
/*************************************************************************
* FUNCTION
* MSDC_Initialize
*
* DESCRIPTION
* Initialize the MS/SD host controller, called only once at drv_init
*
* PARAMETERS*
*
* RETURNS
* 1: initailized failed
* 0: successful
*
* GLOBALS AFFECTED
* gMSDC_Handle
*
*************************************************************************/
extern kal_semid dualMsdcArb;
void MSDC_Probe (void)
{
if (gMSDC_Handle->mIsProbeMSDC)
return;
/* PDN disable first */
MSDC_PDNControl(KAL_FALSE);
#if (CHIP_VER == 1)
msdc_io_init();
#endif
/*check card present or not*/
#if defined(MSDC_HOTPLUG_EN)
#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
if (MSDC_Reg32(MSDC_PS)&MSDC_PS_CDSTS)
gMSDC_Handle->mIsPresent=KAL_FALSE;
else
gMSDC_Handle->mIsPresent=KAL_TRUE;
#else /* _MSDC_INTERNAL_CD_INT_PIN_ */
{
DCL_HANDLE handle;
GPIO_CTRL_READ_T data;
/* when use EINT for card detect,get the status */
handle = DclGPIO_Open(DCL_GPIO, MSDC_INS_GPIO);
DclGPIO_Control(handle, GPIO_CMD_READ, (DCL_CTRL_DATA_T *)&data);
if (data.u1IOData)
gMSDC_Handle->mIsPresent = KAL_FALSE;
else
gMSDC_Handle->mIsPresent = KAL_TRUE;
DclGPIO_Close(handle);
}
#endif
#else /* MSDC_HOTPLUG_EN */
gMSDC_Handle->mIsPresent = KAL_TRUE;
#endif
MSDC_CRIT("[MSDC][%s %d]Card is %s\r\n",__FUNCTION__,__LINE__,
gMSDC_Handle->mIsPresent ? "Present" : "Not Present");
/* If card is not exist, step over the INIT flow */
if (gMSDC_Handle->mIsPresent)
gMSDC_Handle->mIsProbeMSDC = KAL_TRUE;
else {
gMSDC_Handle->mIsProbeMSDC = KAL_FALSE;
goto exit;
}
/*set MSDC as the controller of SD*/
MSDC_SET_FIELD(MSDC_CFG, MSDC_CFG_MODE, 1);
/*reset MSDC ,clear FIFO*/
MSDC_RESET();
MSDC_CLR_FIFO_EX();
MSDC_DEBUG("[MSDC][%s %d]reset MSDC,clear FIFO\r\n",__FUNCTION__,__LINE__);
/*write crc timeout detection*/
MSDC_SetData32(MSDC_PATCH_BIT0,1<<30,(1<<30));
/*Configure To Default Data Timeout */
MSDC_SetData32(SDC_CFG,SDC_CFG_DTOC,(DEFAULT_DTOC<<24));
/*set bus width to 1 */
MSDC_SetBusWidth(BIT_1W);
/* Tuning parameters INIT */
msdc_tune_init();
exit:
MSDC_PDNControl(KAL_TRUE);
/* Shut card power */
MSDC_SetVddPower(KAL_FALSE, gMSDC_Handle->vdd_volt);
/* Defaultly turn VMC to 1.8V to save power */
MSDC_SetSignalPower(KAL_TRUE, gMSDC_Handle->signal_volt);
}
void MSDC_Initialize(void)
{
/* INIT MSDC debug flag */
MSDC_SetDebugLevel(K_NOTICE);
MSDC_CRIT("[MSDC][%s %d]Start init MSDC...\r\n",__FUNCTION__,__LINE__);
/*check MSDC is initalized or not */
if (gMSDC_Handle->mIsInitMSDC)
return;
gMSDC_Handle->mIsProbeMSDC = 0;
/*init gSD*/
kal_mem_set(gSD,0,sizeof(T_SDC_HANDLE));
/* Set voltage of single and card power */
gMSDC_Handle->signal_volt = 1800;
gMSDC_Handle->vdd_volt = 3300;
#if !defined(ATEST_DRV_ENABLE)
/* Get Sleep handler */
gMSDC_Handle->msdc_sm_hdl = SleepDrv_GetHandle(SMP);
MSDC_CRIT("[MSDC][%s %d]MSDC Slp Handler: %d\r\n",
__FUNCTION__, __LINE__, gMSDC_Handle->msdc_sm_hdl);
#endif
/*set clock source */
MSDC_SetClockSource(SRC_80M);
#if (CHIP_VER == 1)
/* Pin MUX setting and IO settings */
msdc_pin_init();
#endif
/*get gpt handle*/
if (gMSDC_Handle->gpt_handle==0)
MSDC_GPTI_GetHandle(&gMSDC_Handle->gpt_handle);
/*clear and disable all interrupt*/
MSDC_ClearBits32(MSDC_INTEN,MSDC_Reg32(MSDC_INTEN));
MSDC_WriteReg32(MSDC_INT,MSDC_Reg32(MSDC_INT));
/* INIT the MSDC related registers */
MSDC_Probe();
/*init INT handle*/
MSDC_INT_Init();
/*set the function support by host*/
gMSDC_Handle->host_support.function1=FUN1_SDR12_DS|FUN1_SDR25_HS|FUN1_SDR50|FUN1_SDR104|FUN1_DDR50;
gMSDC_Handle->host_support.function2=FUN2_DEFAULT;
gMSDC_Handle->host_support.function3=FUN3_TYPE_B;
gMSDC_Handle->host_support.function4=FUN4_200MA|FUN4_400MA|FUN4_600MA|FUN4_800MA;
gMSDC_Handle->mIsInitMSDC = KAL_TRUE;
MSDC_DEBUG("[MSDC][%s %d]finish init MSDC\r\n",__FUNCTION__,__LINE__);
}
/*************************************************************************
* FUNCTION
* MSDC_DeInit
*
* DESCRIPTION
* De-initialize the MS/SD host controller, called only once at drv_init
*
* PARAMETERS*
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
void MSDC_DeInit(void)
{
/* Shutdown Card power Only */
MSDC_SetVddPower(KAL_FALSE, gMSDC_Handle->vdd_volt);
gMSDC_Handle->mIsProbeMSDC = KAL_FALSE;
gMSDC_Handle->mIsInitialized = KAL_FALSE;
return;
}
#ifdef __TST_WRITE_TO_FILE__
/*error recording: add this function to do MSDC reset when error recording*/
void MSDC_ErrorRecordingReset()
{
}
#endif
#ifndef DRV_LSD
/*************************************************************************
* FUNCTION
* BitFieldWrite32
*
* DESCRIPTION
* Write src to dest at mask position
*
* PARAMETERS
* dest: destination to be update
* src: value to be written
* mask: bit mask
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
// Note: mask must be a continuous area during 32bits. eg,
// dest : 00A30000 , src : BF, mask : 0000BF00.
// after BitFieldCpy, dest : 00A3BF00, copy src to dest at mask position.
void BitFieldWrite32(kal_uint32 * dest, kal_uint32 src, kal_uint32 mask)
{
kal_uint8 bit_pos;
kal_uint32 tmp;
bit_pos = 0;
tmp = MSDC_Reg32(dest);
// get bit positoin
while (!((mask >> bit_pos++) & 1));
//use mask clear the corresponding area
tmp &= ~mask;
//shift src to the corresponding positiion
src <<= (bit_pos - 1);
//copy src into destination
tmp |= src;
MSDC_WriteReg32(dest, tmp);
}
#endif
#ifdef MSDC_USED_STUFF
/*************************************************************************
* FUNCTION
* BitFieldRead32
*
* DESCRIPTION
* read src to dest at mask position
*
* PARAMETERS
* dest: destination to store
* src: value to be written
* mask: bit mask
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
// Note: mask must ve continuous area during 32 bits.eg,
// src : 00A3BF00, mask : 00FF0000
// after BitFieldRead, dest : A3
void BitFieldRead32(kal_uint32 * dest, kal_uint32 src, kal_uint32 mask)
{
kal_uint8 bit_pos = 0;
while (!((mask >> bit_pos++) & 1));
src &= mask;
*(kal_uint32 *)dest = src >> (bit_pos - 1);
}
#endif//MSDC_USED_STUFF
// get the bit field value of start_bit with width bits
// note 1) start_bit start from bit 0
// 2) prepare dest with initialized with zeros
// 3) width must less than 32 if using the retrun value as a result
// eg,
// src:00110110, start_bit:2,width:3 => dest:101
void GetBitFieldN(kal_uint8* dest, kal_uint8* src, kal_uint16 start_bit, kal_uint16 width)
{
int i;
kal_uint16 bytes, bits;
//kal_mem_set(dest,0,width/8+1);
kal_mem_set(dest, 0, (width / 8) + (0 == (width % 8) ? 0 : 1));
for ( i = 0; i < width; i++)
{
bytes = (start_bit + i) / 8;
bits = (start_bit + i) % 8;
*(dest + i / 8) |= (kal_uint8)(((*(src + bytes) >> bits) & 1) << (i % 8));
}
/*in MT6238, address of kal_uint32 is checked strictly, and we don't need the return value of this function*/
/*change it's return type to void*/
return ;
}
#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
void MSDC_SetLatchTuning(void)
{
}
#else
void MSDC_SetIOCONRegDLT(void)
{
}
#endif//#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
void msdc_dump_reg(void)
{
int idx;
MSDC_CRIT("****** [00]MSDC_CFG : %x\r\n", MSDC_Reg32(MSDC_CFG));
MSDC_CRIT("****** [04]MSDC_IOCON : %x\r\n", MSDC_Reg32(MSDC_IOCON));
MSDC_CRIT("****** [08]MSDC_PS : %x\r\n", MSDC_Reg32(MSDC_PS));
MSDC_CRIT("****** [0C]MSDC_INT : %x\r\n", MSDC_Reg32(MSDC_INT));
MSDC_CRIT("****** [10]MSDC_INTEN : %x\r\n", MSDC_Reg32(MSDC_INTEN));
MSDC_CRIT("****** [14]MSDC_FIFOCS : %x\r\n", MSDC_Reg32(MSDC_FIFOCS));
MSDC_CRIT("****** [18]MSDC_TXDATA : %x\r\n", MSDC_Reg32(MSDC_TXDATA));
MSDC_CRIT("****** [1C]MSDC_RXDATA : --------\r\n");
MSDC_CRIT("****** [30]SDC_CFG : %x\r\n", MSDC_Reg32(SDC_CFG));
MSDC_CRIT("****** [34]SDC_CMD : %x\r\n", MSDC_Reg32(SDC_CMD));
MSDC_CRIT("****** [38]SDC_ARG : %x\r\n", MSDC_Reg32(SDC_ARG));
MSDC_CRIT("****** [3C]SDC_STS : %x\r\n", MSDC_Reg32(SDC_STS));
MSDC_CRIT("****** [40]SDC_RESP0 : %x\r\n", MSDC_Reg32(SDC_RESP0));
MSDC_CRIT("****** [44]SDC_RESP1 : %x\r\n", MSDC_Reg32(SDC_RESP1));
MSDC_CRIT("****** [48]SDC_RESP2 : %x\r\n", MSDC_Reg32(SDC_RESP2));
MSDC_CRIT("****** [4C]SDC_RESP3 : %x\r\n", MSDC_Reg32(SDC_RESP3));
MSDC_CRIT("****** [50]SDC_BLK_NUM : %x\r\n", MSDC_Reg32(SDC_BLK_NUM));
MSDC_CRIT("****** [58]SDC_CSTS : %x\r\n", MSDC_Reg32(SDC_CSTS));
MSDC_CRIT("****** [5C]SDC_CSTS_EN : %x\r\n", MSDC_Reg32(SDC_CSTS_EN));
MSDC_CRIT("****** [60]SDC_DATCRC_STS : %x\r\n", MSDC_Reg32(SDC_DCRC_STS));
MSDC_CRIT("****** [70]EMMC_CFG0 : %x\r\n", MSDC_Reg32(EMMC_CFG0));
MSDC_CRIT("****** [74]EMMC_CFG1 : %x\r\n", MSDC_Reg32(EMMC_CFG1));
MSDC_CRIT("****** [78]EMMC_STS : %x\r\n", MSDC_Reg32(EMMC_STS));
MSDC_CRIT("****** [7C]EMMC_IOCON : %x\r\n", MSDC_Reg32(EMMC_IOCON));
MSDC_CRIT("****** [80]SD_ACMD_RESP : %x\r\n", MSDC_Reg32(SDC_ACMD_RESP));
MSDC_CRIT("****** [84]SD_ACMD19_TRG : %x\r\n", MSDC_Reg32(SDC_ACMD19_TRG));
MSDC_CRIT("****** [88]SD_ACMD19_STS : %x\r\n", MSDC_Reg32(SDC_ACMD19_STS));
MSDC_CRIT("****** [90]DMA_SA : %x\r\n", MSDC_Reg32(MSDC_DMA_SA));
MSDC_CRIT("****** [94]DMA_CA : %x\r\n", MSDC_Reg32(MSDC_DMA_CA));
MSDC_CRIT("****** [98]DMA_CTRL : %x\r\n", MSDC_Reg32(MSDC_DMA_CTL));
MSDC_CRIT("****** [9C]DMA_CFG : %x\r\n", MSDC_Reg32(MSDC_DMA_CFG));
MSDC_CRIT("****** [A8]DMA_LENGTH : %x\r\n", MSDC_Reg32(MSDC_DMA_LENGTH));
MSDC_CRIT("****** [B0]PATCH_BIT0 : %x\r\n", MSDC_Reg32(MSDC_PATCH_BIT0));
MSDC_CRIT("****** [B4]PATCH_BIT1 : %x\r\n", MSDC_Reg32(MSDC_PATCH_BIT1));
MSDC_CRIT("****** [E0]SD30_PAD_CTL0 : %x\r\n", MSDC_Reg32(MSDC_PAD_CTL0));
MSDC_CRIT("****** [E4]SD30_PAD_CTL1 : %x\r\n", MSDC_Reg32(MSDC_PAD_CTL1));
MSDC_CRIT("****** [E8]SD30_PAD_CTL2 : %x\r\n", MSDC_Reg32(MSDC_PAD_CTL2));
MSDC_CRIT("****** [EC]PAD_TUNE : %x\r\n", MSDC_Reg32(MSDC_PAD_TUNE));
MSDC_CRIT("****** [F0]DAT_RD_DLY0 : %x\r\n", MSDC_Reg32(MSDC_DAT_RDDLY0));
MSDC_CRIT("****** [F4]DAT_RD_DLY1 : %x\r\n", MSDC_Reg32(MSDC_DAT_RDDLY1));
MSDC_CRIT("****** [100]MAIN_VERSION : %x\r\n", MSDC_Reg32(MSDC_VERSION));
MSDC_CRIT("****** [104]ECO_VERSION : %x\r\n", MSDC_Reg32(MSDC_ECO_VER));
for (idx = 0; idx < 26; idx++) {
MSDC_WriteReg32(MSDC_DBG_SEL, idx);
MSDC_CRIT("=*=*=* MSDC_DBG_SEL:%d => MSDC_DBG_OUT:%x\r\n",
idx, MSDC_Reg32(MSDC_DBG_OUT));
}
MSDC_CRIT("====== MSDC Register and Debug Register Dump End ======\r\n");
}
#ifdef _MSDC_DMA_
/*************************************************************************
* FUNCTION
* MSDC_DMAInit
*
* DESCRIPTION
* Initialize MSDC's DMA
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_DMAInit(void)
{
}
void MSDC_StartDMA(void)
{
kal_uint32 ints=MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
MSDC_INTEN_DATCRCERR |MSDC_INTEN_DXFER_DONE |
MSDC_INTEN_BD_CS_ERR | MSDC_INTEN_GPD_CS_ERR;
//kal_uint32 ints=MSDC_DAT_INTS;
kal_uint32 abnormal_ints;
abnormal_ints=MSDC_Reg32(MSDC_INT)&ints;
if(0 != abnormal_ints)
{
/*error, have irq before we enable it*/
MSDC_ERR("[MSDC][%s %d]abnormal irq %x\r\n",__FUNCTION__,__LINE__,abnormal_ints);
MSDC_WriteReg32(MSDC_INT,abnormal_ints);
}
MSDC_SetBits32(MSDC_INTEN, ints);
MSDC_SET_FIELD(MSDC_DMA_CTL, MSDC_DMA_CTL_START, 1);
gMSDC_Handle->is_timeout=KAL_FALSE;
MSDC_START_TIMER(MSDC_DMA_DAT_TMO);
}
SDC_CMD_STATUS MSDC_ConfigDMA(kal_uint32 * buffer,kal_uint32 num,msdc_gpd_t * gpd_ptr,kal_bool isLastBuf)
{
kal_uint32 dma_ctl_arg;
#define BURST_8Byte 3
#define BURST_16Byte 4
#define BURST_32Byte 5
#define BURST_64Byte 6
/*if (gpd_ptr==NULL)
{
gMSDC_Handle->error=ERR_ARGUMENT;
#ifdef MSDC_DEBUG_PRINT
dbg_print("[MSDC][ERROR][%s %d]gpd_ptr point to zero\r\n",__FUNCTION__,__LINE__);
#endif
return ERR_ARGUMENT;
}*/
//set to DMA mode
//BitFieldWrite32((kal_uint32 *)MSDC_CFG, 0, MSDC_CFG_PIO);
MSDC_ClearBits32(MSDC_CFG,MSDC_CFG_PIO);
gMSDC_Handle->dma_xfer=1;
if ((buffer==NULL) && (gpd_ptr != NULL))
{
/*use link list based DMA */
#ifdef MSDC_DMA_CHKSUM_EN
/*Enable descriptor 's checksum*/
MSDC_SET_FIELD(MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1);
#else
/*Disable descriptor 's checksum*/
MSDC_SET_FIELD(MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 0);
#endif
/*descriptor mode and burst size=64Bytes*/
dma_ctl_arg=(BURST_64Byte<<12)|MSDC_DMA_CTL_MODE;
MSDC_WriteReg32(MSDC_DMA_CTL,dma_ctl_arg);
/*write DMA start address to GPD's physical address*/
MSDC_WriteReg32(MSDC_DMA_SA,gpd_ptr);
}
else if((buffer != NULL)&& (gpd_ptr == NULL))
{
/*use basic DMA*/
/*burst size\last buffer*/
dma_ctl_arg = (isLastBuf==KAL_TRUE)? ((BURST_64Byte<<12)|MSDC_DMA_CTL_LASTBUF) : (BURST_64Byte<<12);
MSDC_WriteReg32(MSDC_DMA_CTL,dma_ctl_arg);
/*set xfer size*/
MSDC_WriteReg32(MSDC_DMA_LENGTH,num);
/*set address*/
MSDC_WriteReg32(MSDC_DMA_SA,buffer);
}
else
{
//wrong argument
}
return NO_ERROR;
}
SDC_CMD_STATUS MSDC_WaitDMADone()
{
kal_uint32 status;
kal_uint32 ints= MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
MSDC_INTEN_DATCRCERR |MSDC_INTEN_DXFER_DONE |
MSDC_INTEN_BD_CS_ERR | MSDC_INTEN_GPD_CS_ERR;
/*wait DMA done*/
kal_retrieve_eg_events(gMSDC_Handle->MSDC_Events,EVENT_XFER_DONE|EVENT_DMA_DONE,KAL_OR_CONSUME,&status,KAL_SUSPEND);
MSDC_STOP_TIMER();
MSDC_DEBUG("[MSDC][%s]msdc_int=%x\r\n",__FUNCTION__,gMSDC_Handle->msdc_int);
if (gMSDC_Handle->is_timeout)
{
MSDC_ERR("[MSDC][%s %d]wait DMA done GPT timeout\r\n",__FUNCTION__,__LINE__);
msdc_dump_reg();
gMSDC_Handle->error=MSDC_GPT_TIMEOUT_ERR;
}
/*Disable interrupt*/
MSDC_ClearBits32(MSDC_INTEN,ints);
/*stop dma*/
MSDC_STOP_DMA();
return gMSDC_Handle->error;
}
kal_uint32 MSDC_CheckCardBusy(kal_bool send_stop,kal_uint32 timeout_ms)
{
kal_uint32 start_time,status;
kal_uint32 err,count=0;
start_time = drv_get_current_time();
do{
err=SD_GetStatus(gSD->mRCA, &status);
if(err)
{
break;
}
count++;
if(count%5000==0)
{
if(send_stop)
{
SD_StopTrans();
}
}
}while((!(status&R1_READY_FOR_DATA_8)||(R1_CURRENT_STATE(status)==7))&&(drv_get_duration_ms(start_time) <=timeout_ms));
if (!(drv_get_duration_ms(start_time) <=timeout_ms))
{
MSDC_ERR("[MSDC][%s %d]card busy timeout\r\n",__FUNCTION__,__LINE__);
gMSDC_Handle->error=err=ERR_CARD_BUSY_TIMEOUT;
}
return err;
}
/************************************************************************
* FUNCTION
* MSDC_DMATransferFinal_In_Callback
*
* DESCRIPTION
* Initialize MSDC's DMA
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
#if defined(MSDC_START_DMA_IN_CALLBACK)
void MSDC_DMATransferFinal_In_Callback(void)
{
}
kal_uint32 MSDC_DMATransferFinal(void)
{
}
#endif
/*************************************************************************
* FUNCTION
* MSDC_DMATransfer
*
* DESCRIPTION
* MSDC using DAM for data transfer
*
* PARAMETERS
* adrs: data buffer
* count: bytes to be transfered
* isTx: ture for move data from MSDC to data buffer and vise versa
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
extern kal_bool FTL_isPollingMode();
void MSDC_DMATransferFirst( kal_bool isWrite,kal_bool isLinkListBuf)
{
kal_uint32 * adrs;
kal_set_eg_events(gMSDC_Handle->MSDC_Events,0,KAL_AND);
if (isLinkListBuf)
{
/*configure DMA*/
MSDC_ConfigDMA(NULL,gMSDC_Handle->total_count,(msdc_gpd_t *)gMSDC_Handle->buf_addr,1);
}
else
{
adrs=gMSDC_Handle->buf_addr;
#ifdef MSDC_CACHED_SUPPORT
if (gMSDC_Handle->isRomSpace)
{
gMSDC_Handle->trans_count=(gMSDC_Handle->total_count > MSDC_UNCACHED_TRANSFER_SIZE) ? (MSDC_UNCACHED_TRANSFER_SIZE) : gMSDC_Handle->total_count;
/*copy from upper application buffer*/
if (isWrite)
{
kal_mem_cpy((void *)msdc_uncachedBuf,(void*)gMSDC_Handle->buf_addr,gMSDC_Handle->trans_count);
}
adrs=(kal_uint32 *)msdc_uncachedBuf;
}
else if (gMSDC_Handle->isCachedBuf)
{
//clear cache
gMSDC_Handle->trans_count=(gMSDC_Handle->total_count > MSDC_DMA_BURSTLEN_LIMIT) ? (MSDC_DMA_BURSTLEN_LIMIT) : gMSDC_Handle->total_count;
clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)gMSDC_Handle->buf_addr),CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)gMSDC_Handle->buf_addr,gMSDC_Handle->trans_count));
Data_Mem_Barrier();
}
else
#endif
{
gMSDC_Handle->trans_count=(gMSDC_Handle->total_count > MSDC_DMA_BURSTLEN_LIMIT) ? (MSDC_DMA_BURSTLEN_LIMIT) : gMSDC_Handle->total_count;
}
/*configure DMA*/
MSDC_ConfigDMA(adrs,gMSDC_Handle->trans_count,NULL,(gMSDC_Handle->total_count==gMSDC_Handle->trans_count));
}
}
#if !defined(MSDC_START_DMA_IN_CALLBACK)
kal_uint32 MSDC_DMATransferFinal(kal_bool isWrite,kal_bool isLinkListBuf)
{
kal_uint32 status;
while(1)
{
/*start DMA*/
MSDC_StartDMA();
/*wait DMA finish*/
status=MSDC_WaitDMADone();
if (status!=NO_ERROR)
{
MSDC_ERR("[MSDC][%s %d]INTS<%x>\r\n",__FUNCTION__,__LINE__,gMSDC_Handle->msdc_int);
goto done;
}
if (isLinkListBuf)
{
MSDC_DEBUG("[MSDC]link list DMA finish\r\n");
break;
}
else
{
/*copy RX data when use cached buffer*/
#ifdef MSDC_CACHED_SUPPORT
if (gMSDC_Handle->isCachedBuf)
{
/*if (!isWrite)
{
kal_mem_cpy((void *)gMSDC_Handle->buf_addr,(void *)msdc_uncachedBuf,gMSDC_Handle->trans_count);
}*/
//invalidate_dcache((gMSDC_Handle->buf_addr&~CPU_CACHE_LINE_SIZE_MASK),(gMSDC_Handle->trans_count+CPU_CACHE_LINE_SIZE_MASK)&~CPU_CACHE_LINE_SIZE_MASK);
}
#endif
/*check need do further transfer or not */
gMSDC_Handle->total_count-=gMSDC_Handle->trans_count;
if (gMSDC_Handle->total_count==0)
{
gMSDC_Handle->error=NO_ERROR;
goto done;
}
gMSDC_Handle->buf_addr+=gMSDC_Handle->trans_count;
MSDC_DMATransferFirst( isWrite,isLinkListBuf);
}
}
done:
return status;
}
#endif //!defined(MSDC_START_DMA_IN_CALLBACK)
#endif // DMA
void* GetMsdcHandle(kal_uint8 id)
{
return (void*)&MSDC_Blk[id];
}
#ifdef R1B_INTERRUPT_MODE
static void MSDC_R1B_Init()
{
}
#endif
// ===========================================================
// MSDC common lock
// ===========================================================
#if !defined(__FUE__) && !defined(__UBL__)
void init_MSDC_lock(PMSDC_LOCK_TAG lock, const kal_char *str)
{
if (lock->mtd_mutex == NULL)
{
strcpy((char *)lock->name, str);
lock->mtd_mutex = kal_create_mutex((kal_char *)lock->name);
lock->lock_count = 0;
lock->owner_id = NULL;
}
}
static kal_uint8 msdc_lock_user = 0;
void get_MSDC_lock(PMSDC_LOCK_TAG lock)
{
if (msdc_lock_user > 0)
;//ASSERT(0); // init debugging purpose
else
msdc_lock_user ++;
if ( kal_query_systemInit() || INT_QueryExceptionStatus() )
return;
if (kal_if_hisr() == KAL_TRUE || kal_if_lisr() == KAL_TRUE)
{
kal_uint32 retaddr0 = 0;
GET_RETURN_ADDRESS(retaddr0);
EXT_ASSERT(0, retaddr0, 0, 0);
}
if ( kal_get_current_task() == lock->owner_id )
{
force_ASSERT(0 != lock->lock_count, lock->lock_count, (kal_uint32)lock->owner_id, (kal_uint32)lock->mtd_mutex);
lock->lock_count++;
}
else
{
if (lock->mtd_mutex == NULL)
{
init_MSDC_lock(lock, (const kal_char *)lock->name);
}
kal_take_mutex(lock->mtd_mutex);
// lock->owner_id = kal_get_task_self_id();
lock->owner_id = kal_get_current_task();
lock->lock_count++;
}
}
void free_MSDC_lock(PMSDC_LOCK_TAG lock)
{
if (msdc_lock_user != 1)
;//ASSERT(0); // init debugging purpose
else
msdc_lock_user --;
if ( kal_query_systemInit() || INT_QueryExceptionStatus() )
return;
if ( kal_get_current_task() == lock->owner_id )
{
force_ASSERT(lock->lock_count > 0, lock->lock_count, (kal_uint32)lock->owner_id, (kal_uint32)lock->mtd_mutex);
lock->lock_count--;
if (0 == lock->lock_count)
{
lock->owner_id = NULL;
if (lock->mtd_mutex != NULL)
kal_give_mutex(lock->mtd_mutex);
}
}
else
{
force_ASSERT(0, (kal_uint32)lock->owner_id, (kal_uint32)kal_get_current_task(), (kal_uint32)lock->mtd_mutex);
}
}
#else /* __FUE__, __UBL__ */
//#define init_MSDC_lock(x)
//#define get_MSDC_lock(x)
//#define free_MSDC_lock(x)
#endif /* !defined(__FUE__) && !defined(__UBL__) */
#ifdef _MSDC_INT_
#ifdef USE_INT26_CARD_DETECTION
void MSDC_CardDetect_LISR(void)
{
}
#endif //USE_INT26_CARD_DETECTION
#ifdef DRV_LSD
kal_uint32 MSDC_CARD_INSERT_COUNTER, MSDC_CARD_REMOVE_COUNTER;
kal_uint32 notifiedFMT;//this variable is to sync the state, since we only allow FMT get disk infor to be the first operation that access SD
void MSDC_LSD_HISR(void)
{
}
void MSDC_unsealMountOperation(void)
{
/*notifiedFMT may be modified by FMT and MMI tasks, but it is no need to protect this, any task that preempt FMT just get mount fail*/
if (1 == notifiedFMT) /*FMT may call this function no matter card exits or not*/
{
notifiedFMT = 2;
}
}
#endif
#if !defined(_MSDC_INTERNAL_CD_INT_PIN_)
void MSDC_CD_Entry()
{
/* Reverse the polarity */
cardDetectionEINTPolarity = !cardDetectionEINTPolarity;
EINT_Set_Polarity(MSDC_EINT_NUM, cardDetectionEINTPolarity);
gMSDC_Handle->mIsChanged=KAL_TRUE;
/*memory card insertion\removal */
if (!cardDetectionEINTPolarity)
{
gMSDC_Handle->mIsPresent=KAL_FALSE;
gMSDC_Handle->mIsInitialized=KAL_FALSE;
#ifdef MSDC_MUST_RECORD_PLUGOUT
if (KAL_FALSE == gMSDC_Handle->mIsPresent)
gMSDC_Handle->MSDC_everPlugOut = KAL_TRUE;
#endif//MSDC_MUST_RECORD_PLUGOUT
MSDC_CRIT("[MSDC]Card Remove(EINT)\r\n");
MSDC_DeInit();
}
else
{
gMSDC_Handle->mIsPresent=KAL_TRUE;
gMSDC_Handle->mIsInitialized=KAL_FALSE;
MSDC_CRIT("[MSDC]Card Insert(EINT)\r\n");
MSDC_Probe();
}
}
#endif
/*************************************************************************
* FUNCTION
* MSDC_INT_Init
*
* DESCRIPTION
* Initialize MSDC's interrupt
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_INT_Init(void)
{
/*create events group*/
gMSDC_Handle->MSDC_Events=kal_create_event_group("MSDC Event");
/*register HISR*/
DRV_Register_HISR(DRV_MSDC_HISR_ID,MSDC_HISR_Entry);
/*register LISR*/
IRQ_Register_LISR(MD_IRQID_MSDC0,MSDC_LISR,"MSDC ISR");
IRQSensitivity(MD_IRQID_MSDC0,LEVEL_SENSITIVE);
IRQUnmask(MD_IRQID_MSDC0);
/*clear IRQ */
MSDC_WriteReg32(MSDC_INT,MSDC_Reg32(MSDC_INT));
/*register IRQ for card detect*/
/*enable card detect interrupt*/
#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
/*enable card detect*/
MSDC_SET_FIELD(MSDC_PS, MSDC_PS_CDEN, 1);
MSDC_SET_FIELD(MSDC_INTEN, MSDC_INTEN_CDSC, 1);
#else
/* Polarity setting, default triggered by low level */
cardDetectionEINTPolarity = EINT_DefaultPolarity;
/* SW debounce time is 300ms */
MSDC_debounceTime=30;
EINT_Mask(MSDC_EINT_NUM); //need check the MSDC_EINT_NO ,unused current time
/* Level trigger */
EINT_Set_Sensitivity(MSDC_EINT_NUM, KAL_FALSE);
EINT_Registration(MSDC_EINT_NUM,KAL_TRUE,cardDetectionEINTPolarity,MSDC_CD_Entry,KAL_TRUE);
EINT_SW_Debounce_Modify(MSDC_EINT_NUM,MSDC_debounceTime);
EINT_UnMask(MSDC_EINT_NUM);
#endif
}
void MSDC_LISR(void)
{
/*Mask IRQ*/
IRQMask(MD_IRQID_MSDC0);
/*save IRQ information*/
gMSDC_Handle->msdc_int=MSDC_Reg32(MSDC_INT);
/*call hisr*/
drv_active_hisr(DRV_MSDC_HISR_ID);
}
void MSDC_DatIrqHandle(kal_uint32 intsts)
{
if (intsts & MSDC_INT_XFER_COMPL){
gMSDC_Handle->error=NO_ERROR;
kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_XFER_DONE,KAL_OR);
}
else if (intsts & MSDC_INT_DXFER_DONE)
{
gMSDC_Handle->error=NO_ERROR;
kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_DMA_DONE,KAL_OR);
}
else
{
/*mean some error */
if (intsts & MSDC_INT_DATCRCERR)
{
gMSDC_Handle->error=ERR_DAT_CRCERR;
MSDC_ERR("[MSDC][%s %d]CMD%d DMA DAT CRCERR!\r\n",__FUNCTION__,
__LINE__, gMSDC_Handle->cmd & 0x3F);
}
else if (intsts & MSDC_INT_DATTMO)
{
gMSDC_Handle->error=ERR_DAT_TIMEOUT;
MSDC_ERR("[MSDC][%s %d]CMD%d DMA DAT TMO!\r\n",__FUNCTION__,
__LINE__, gMSDC_Handle->cmd & 0x3F);
} else if (intsts & MSDC_INT_BD_CS_ERR) {
gMSDC_Handle->error = ERR_DAT_TIMEOUT;
MSDC_ERR("[MSDC][%s %d]CMD%d DMA BD checksum ERR!\r\n",__FUNCTION__,
__LINE__, gMSDC_Handle->cmd & 0x3F);
} else if (intsts & MSDC_INT_GPD_CS_ERR) {
gMSDC_Handle->error = ERR_DAT_TIMEOUT;
MSDC_ERR("[MSDC][%s %d]CMD%d DMA GPD checksum ERR!\r\n",__FUNCTION__,
__LINE__, gMSDC_Handle->cmd & 0x3F);
}
/*for poll mode exit*/
gMSDC_Handle->abort=1;
if (gMSDC_Handle->dma_xfer)
{
kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_XFER_DONE,KAL_OR);
}
}
}
void MSDC_CmdIrqHandle(kal_uint32 intsts)
{
if ((intsts&MSDC_INT_CMDRDY)||(intsts&MSDC_INT_ACMDRDY)||(intsts&MSDC_INT_ACMD19_DONE))
{
gMSDC_Handle->error=NO_ERROR;
}
else if ((intsts&MSDC_INT_RSPCRCERR)||(intsts&MSDC_INT_ACMDCRCERR))
{
gMSDC_Handle->error=ERR_CMD_RSPCRCERR;
}
else if ((intsts&MSDC_INT_ACMDTMO)||(intsts&MSDC_INT_CMDTMO))
{
gMSDC_Handle->error=ERR_CMD_TIMEOUT;
}
kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_CMD_DONE,KAL_OR);
}
void MSDC_CardDetectHandle(kal_uint32 intsts)
{
#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
gMSDC_Handle->mIsChanged=KAL_TRUE;
/*memory card insertion\removal */
if (MSDC_Reg32(MSDC_PS)&MSDC_PS_CDSTS)
{
/*Card detection pin is logic high*/
gMSDC_Handle->mIsPresent=KAL_FALSE;
gMSDC_Handle->mIsInitialized=KAL_FALSE;
#ifdef MSDC_MUST_RECORD_PLUGOUT
if (KAL_FALSE == gMSDC_Handle->mIsPresent)
gMSDC_Handle->MSDC_everPlugOut = KAL_TRUE;
#endif//MSDC_MUST_RECORD_PLUGOUT
MSDC_CRIT("[MSDC]Card Remove\r\n");
MSDC_DeInit();
}
else
{
/*Card detection pin is logic low*/
gMSDC_Handle->mIsPresent=KAL_TRUE;
gMSDC_Handle->mIsInitialized=KAL_FALSE;
MSDC_CRIT("[MSDC]Card Insert\r\n");
MSDC_Probe();
}
#endif
}
/*************************************************************************
* FUNCTION
* MSDC_HISR_Entry
*
* DESCRIPTION
* Set corresponding enevt and wake up waiting task.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_HISR_Entry(void)
{
kal_uint32 cmdsts =MSDC_INT_CMDRDY|MSDC_INT_CMDTMO|MSDC_INT_RSPCRCERR;
kal_uint32 acmdsts =MSDC_INT_ACMDRDY|MSDC_INT_ACMDTMO|MSDC_INT_ACMDCRCERR|MSDC_INT_ACMD19_DONE;
kal_uint32 datsts =MSDC_INT_XFER_COMPL | MSDC_INT_DXFER_DONE |
MSDC_INT_DATCRCERR | MSDC_INT_DATTMO |
MSDC_INT_BD_CS_ERR | MSDC_INT_GPD_CS_ERR;
kal_uint32 intsts_pure;
kal_uint32 inten, intsts;
/*Mask IRQ*/
IRQMask(MD_IRQID_MSDC0);
/*save IRQ information*/
gMSDC_Handle->msdc_int=MSDC_Reg32(MSDC_INT);
intsts_pure=gMSDC_Handle->msdc_int;
inten=MSDC_Reg32(MSDC_INTEN);
intsts=intsts_pure&inten;
/*clear all interrupt*/
MSDC_WriteReg32(MSDC_INT,intsts);
/*data transfer interrupt*/
if (intsts&datsts)
{
MSDC_DatIrqHandle(intsts);
}
/*command interrupt*/
if (intsts&(cmdsts|acmdsts))
{
MSDC_CmdIrqHandle(intsts);
}
/*card detect interrupt*/
if(intsts & MSDC_INT_CDSC)
{
MSDC_CardDetectHandle(intsts);
}
/*mmc interrupt*/
/*unmask irq*/
IRQUnmask(MD_IRQID_MSDC0);
}
/*************************************************************************
* FUNCTION
* MSDC_DMA_Callback
*
* DESCRIPTION
* Call back while DMA has done the data transfer.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_DMA_Callback(void)
{
}
#ifdef DRV_MSDC_SHARE_BY_SWITCH
void MSDC_changeSwContext(sd_select_enum sel)
{
gMSDC_Handle = &MSDC_Blk[sel];
gSD = &gSD_blk[sel];
}
/*
this function do not consider race condition issue, caller should make sure this function is called without risk
currently, this function is called in sdio_drv.c and sd_drv.c
*/
void MSDC_backupHwSetting()
{
/*backup MSDC_CFG, MSDC_IOCON, SDC_CFG*/
gMSDC_Handle->setting_MSDC_CFG = MSDC_Reg32(MSDC_CFG);
gMSDC_Handle->setting_MSDC_IOCON = MSDC_Reg32(MSDC_IOCON);
gMSDC_Handle->setting_SDC_CFG = MSDC_Reg32(SDC_CFG);
}
void MSDC_retreiveHwSetting()
{
MSDC_WriteReg32(MSDC_CFG, gMSDC_Handle->setting_MSDC_CFG);
MSDC_WriteReg32(MSDC_IOCON, gMSDC_Handle->setting_MSDC_IOCON);
MSDC_WriteReg32(SDC_CFG, gMSDC_Handle->setting_SDC_CFG);
}
#endif
#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
void MSDC_Switch_Card(sd_select_enum sel)
{
}
#endif
#endif //end of MSDC_INT
void MSDC_turnOnVMC(kal_bool turnOnLdo)
{
}
#if defined(MSDC_TRACE_LEVEL3)
void MSDC_add_dbg_msg( msdc_dbg_Event event, kal_uint32 data1, kal_uint32 data2)
{
}
#endif
#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
void MSDC_Switch_SDIO(sd_select_enum sel)
{
}
#endif
#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
/*following should be the value defined in custom files*/
#define MSDC_SWITCH_2_SD 1
#define MSDC_SWITCH_2_SDIO 0
#define MSDC_SWITCH_GPIO 20
typedef enum
{
MSDC_SWITCH_DIRECTION_SD,
MSDC_SWITCH_DIRECTION_SDIO
} MSDC_SWITCH_DIRECTION;
void MSDC_Switch_init()
{
}
/*
direction:
0 : cmmb
1 : sd card
*/
void MSDC_Switch(sd_select_enum direction)
{
}
#endif
#else
#ifdef DRV_LSD
void MSDC_LSD_HISR(void)
{
}
#endif
#endif // end of (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__))
#endif//!defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
#else //DRV_MSDC_OFF
#include "kal_public_api.h" //MSBB change #include "kal_release.h"
#include "msdc_def.h"
/*
#include "kal_public_api.h" //MSBB change #include "kal_release.h"
//RHR REMOVE
#include "syscomp_config.h"
#include "task_config.h"
#include "stacklib.h"
#include "eint.h"
#include "fat_fs.h"
*/
//RHR
#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
#include "kal_public_api.h" //MSBB change #include "app_ltlcom.h"
#include "intrCtrl.h"
#include "reg_base.h"
#include "drvpdn.h"
//#include "gpt_sw.h"
#include "drv_comm.h"
#include "drv_hisr.h"
#include "msdc_def.h"
#include "dcl.h"
/* Debug log */
kal_uint32 MSDC_DebugLevel;
#define LDO_VMC 0
#define LDO_VMCH 1
#define LDO_VIO18_PMU 2
static kal_uint32 g_msdc0_io = PMU_VOLT_03_300000_V;
static kal_uint32 g_msdc0_card = PMU_VOLT_03_300000_V;
static kal_uint32 hwPowerOn(kal_uint32 powerID, PMU_VOLTAGE_ENUM powerVolt)
{
PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
PMU_CTRL_LDO_BUCK_SET_VOLTAGE pmu_volsel;
DCL_HANDLE handle;
/* Open PMU handle */
handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
switch(powerID) {
case LDO_VMC:
/* Set enable control */
pmu_en.mod = VMC;
pmu_en.enable = 1;
/* Set voltage */
pmu_volsel.mod = VMC;
pmu_volsel.voltage = powerVolt;
DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
break;
case LDO_VMCH:
/* Set enable control */
pmu_en.mod = VMCH;
pmu_en.enable = 1;
/* Set voltage */
pmu_volsel.mod = VMCH;
pmu_volsel.voltage = powerVolt;
DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
break;
default:
break;
}
/* Close PMU handle */
DclPMU_Close(handle);
return 1;
}
static kal_uint32 hwPowerDown(kal_uint32 powerID)
{
PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
DCL_HANDLE handle;
/* Open PMU handle */
handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
switch(powerID) {
case LDO_VMC:
/* Set enable control */
pmu_en.mod = VMC;
pmu_en.enable = 0;
DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
break;
case LDO_VMCH:
/* Set enable control */
pmu_en.mod = VMCH;
pmu_en.enable = 0;
DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
break;
default:
break;
}
/* Close PMU handle */
DclPMU_Close(handle);
return 1;
}
static kal_uint32 msdc_ldo_power(kal_uint32 on, kal_uint8 powerId,
PMU_VOLTAGE_ENUM powerVolt, kal_uint32 *status)
{
if (on) { // want to power on
if (*status == 0) { // can power on
hwPowerOn(powerId, powerVolt);
*status = powerVolt;
} else if (*status == powerVolt) {
} else { // for sd3.0 later
hwPowerDown(powerId);
hwPowerOn(powerId, powerVolt);
*status = powerVolt;
}
} else { // want to power off
if (*status != 0) { // has been powerred on
hwPowerDown(powerId);
*status = 0;
} else {
}
}
return 0;
}
kal_bool MSDC_SetVddPower(kal_bool on, kal_uint32 volt)
{
kal_bool ret =KAL_TRUE;
if (volt == 3300)
{
msdc_ldo_power(on, LDO_VMCH, PMU_VOLT_03_300000_V, &g_msdc0_card);
}
else
{
ret = KAL_FALSE;
}
return ret;
}
kal_bool MSDC_SetSignalPower(kal_bool on,kal_uint32 volt)
{
kal_bool ret =KAL_TRUE;
if (volt == 3300)
{
msdc_ldo_power(on, LDO_VMC, PMU_VOLT_03_300000_V, &g_msdc0_io);
}
else if (volt ==1800)
{
msdc_ldo_power(on, LDO_VMC, PMU_VOLT_01_800000_V, &g_msdc0_io);
}
else
{
ret = KAL_FALSE;
}
return ret;
}
/*here are dummy API*/
void MSDC_Initialize(void)
{
/* INIT MSDC debug flag */
MSDC_SetDebugLevel(K_WARNIN);
/* Shut card power and signal power */
MSDC_SetVddPower(KAL_FALSE, 3300);
MSDC_SetSignalPower(KAL_FALSE, 3300);
}
void MSDC_PDNControl(kal_bool ON) {}
int MSDC_GetCardStatus(void * DriveData, int AckType) {return 0;}
//kal_bool MSDC_GetMediaChanged(void * id) {}
kal_bool MSDC_GetMediaChanged(sd_select_enum id) {return 0;}
MSDC_HANDLE MSDC_Blk[SD_NUM];
MSDC_HANDLE *gMSDC_Handle = &(MSDC_Blk[0]);
//kal_bool MSDC_everPlugOut;
#endif //DRV_MSDC_OFF