⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdcontrol.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//------------------------------------------------------------------------------
//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
//  Use of this source code is subject to the terms of the Microsoft end-user
//  license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
//  If you did not accept the terms of the EULA, you are not authorized to use
//  this source code. For a copy of the EULA, please see the LICENSE.RTF on
//  your install media.
//
//------------------------------------------------------------------------------
//
//  Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
//  Copyright (C) 2004, 2005, 2006 Freescale Semiconductor, Inc. All Rights Reserved
//  THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
//  BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
//  FREESCALE SEMICONDUCTOR, INC.
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
//  File:  sdcontrol.cpp
//
//  Implementation of SDHC common Device Driver
//
//  This file implements common SDHC functions 
//  This driver is still pending to PMIC integration. During driver power down and power up, 
//  hardware reset is not implemented yet. 
//------------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include "mxarm11.h"
#include "sdhc.h"
#include "sdbusdriver.h"

/*******************************************************************************
 GLOBAL OR STATIC VARIABLES  
*******************************************************************************/
/*******************************************************************************
 STATIC FUNCTION PROTOTYPES  
*******************************************************************************/
static DWORD SDControllerIstThread(PSDH_HARDWARE_CONTEXT pHCDevice);
static DWORD SDControllerBusyResponseThread(PSDH_HARDWARE_CONTEXT pHCDevice);
static void IndicateBusRequestComplete(PSDH_HARDWARE_CONTEXT pController,
                                       PSD_BUS_REQUEST pRequest,
                                       SD_API_STATUS status);
static BOOL HandleCommandComplete(PSDH_HARDWARE_CONTEXT pController);
static BOOL HandleTransferDone(PSDH_HARDWARE_CONTEXT pController);
static void SetRate(PSDH_HARDWARE_CONTEXT pHc, PDWORD pRate, BOOL fSetNewRate);
static void SetClock(PSDH_HARDWARE_CONTEXT pController, BOOL Start) ;
static void SoftwareReset(PSDH_HARDWARE_CONTEXT pController, BOOL bResetClock);
static void SetHardwarePowerState(PSDH_HARDWARE_CONTEXT pHc, CEDEVICE_POWER_STATE ds);
static void ProcessCardInsertion(void *pContext);
static void ProcessCardRemoval(void *pContext);
static void InitGlobals(PSDH_HARDWARE_CONTEXT pController);
static inline BOOL TransferIsSDIOAbort(PSD_BUS_REQUEST pRequest);
static BOOL InitDMA(PSDH_HARDWARE_CONTEXT pController) ;
static BOOL DeInitDMA(PSDH_HARDWARE_CONTEXT pController) ;
static BOOL SetupCardPresenceDetect(PSDH_HARDWARE_CONTEXT pHardwareContext) ; 
static void SDCardPresenceDetect(void *pContext);
static void CleanupCardPresenceDetect(PSDH_HARDWARE_CONTEXT pHardwareContext);
static void DumpRegisters(PSDH_HARDWARE_CONTEXT pHc);
static void DumpStatusRegister(PSDH_HARDWARE_CONTEXT pHc);

/*******************************************************************************
 EXPORTED FUNCTIONS
*******************************************************************************/
//------------------------------------------------------------------------------
//
// Function: SDInitialize
//
// Initialize the the MMC Controller
//
// Parameters:
//       pHardwareContext[in] - newly allocated hardware context
//
// Returns:
//      SD_API_STATUS code
//
//------------------------------------------------------------------------------
SD_API_STATUS SDInitialize(PSDCARD_HC_CONTEXT pHCContext)
{
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;   // intermediate status
    PHYSICAL_ADDRESS phyAddr;
    PSDH_HARDWARE_CONTEXT pHardwareContext;       // hardware context
    pHardwareContext = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+SDInitialize: Initialize the SDHC\r\n")));
    InitializeCriticalSection(&pHardwareContext->ControllerCriticalSection);

    // Init  globals
    InitGlobals(pHardwareContext);

    if (pHardwareContext->ControllerIndex == 1)
    {
        DEBUGMSG(ZONE_FUNCTION, (TEXT("SDInitialize: Controller 1\r\n")));
        //Virtual memory mapping
        phyAddr.QuadPart = CSP_BASE_REG_PA_SDHC1 ;
    } 
    else if (pHardwareContext->ControllerIndex == 2)
    {
        DEBUGMSG(ZONE_FUNCTION, (TEXT("SDInitialize: Controller 2\r\n")));
        //Virtual memory mapping
        phyAddr.QuadPart = CSP_BASE_REG_PA_SDHC2 ;
    } 
    else
    {
        ERRORMSG(ZONE_ERROR, (TEXT("SDInitialize:  We only have 2 controllers!!\r\n")));
        goto exitInit;
    }

#if !VPMX31
    //Start SDHC BSP specific initialization 
    if (!BSPSdhcInit(pHardwareContext->ControllerIndex))
    {
        ERRORMSG(ZONE_ERROR, (TEXT("BSPSdhcInit FAIL!\r\n")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }
#endif //VPMX31
    
    // Power off the card slot to save power
    BSPSetVoltageSlot(pHardwareContext->ControllerIndex, 0);
    // cut the clocks to the controller to save power
    BSPSdhcSetClockGatingMode(FALSE, pHardwareContext->ControllerIndex);

    //Setup IOMUX
    BspSdhcSetIOMux(pHardwareContext->ControllerIndex);

    //Get IRQ and DMA channels for SDHC
    pHardwareContext->dwIrqSDHC = BspSdhcGetIrq(pHardwareContext->ControllerIndex);
    pHardwareContext->DmaReqTx  = (DDK_DMA_REQ)BspSdhcGetSdmaChannelTx(pHardwareContext->ControllerIndex); 
    pHardwareContext->DmaReqRx  = (DDK_DMA_REQ)BspSdhcGetSdmaChannelRx(pHardwareContext->ControllerIndex); 

    // Map Virtual Address
    pHardwareContext->pSDMMCRegisters = (PCSP_SDHC_REG) MmMapIoSpace(phyAddr, sizeof(CSP_SDHC_REG), FALSE);
    if (pHardwareContext->pSDMMCRegisters == NULL)
    {
        ERRORMSG(ZONE_ERROR, (TEXT("SDInitialize:  MmMapIoSpace failed!\r\n")));
        goto exitInit;
    }

    if (BspSdhcIsSdmaSupported(pHardwareContext->ControllerIndex) == TRUE)
    {
        RETAILMSG(1, (TEXT("SDHC: DMA Support Enabled for Controller %d\r\n"), pHardwareContext->ControllerIndex));
        // Initialize DMA 
        if (!InitDMA(pHardwareContext))
        {
            ERRORMSG(ZONE_ERROR, (TEXT("MMCSD_DMAInit: cannot init DMA!\r\n")));
            status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
            goto exitInit;
        }
    }
    else
    {
        RETAILMSG(1, (TEXT("SDHC: DMA Support Disabled for Controller %d\r\n"), pHardwareContext->ControllerIndex));
    }

    // controller clock gating between cmds is supported only for memory cards. This decision is taken later.
    pHardwareContext->fClockGatingSupported = FALSE;
    pHardwareContext->fClockGatedOff = TRUE; // controller clocks are not enabled here

    // Setup card detection mechanism
    if (!SetupCardPresenceDetect(pHardwareContext))
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    //Create interrupt event
    pHardwareContext->hControllerInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
    if (NULL == pHardwareContext->hControllerInterruptEvent)
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }
	
#ifdef SD_R1B_BUSYWAIT_WORKAROUND
    //Create busy wait event
    pHardwareContext->hControllerBusyEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
    if (NULL == pHardwareContext->hControllerBusyEvent)
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    // Initialize SDControllerBusyResponseThread() to handle busy response commands
    DWORD busyThreadID;                         
    // create the interrupt thread for controller interrupts
    pHardwareContext->hControllerBusyResponseThread= CreateThread(NULL,
                                                                0,
                                                                (LPTHREAD_START_ROUTINE)
                                                                SDControllerBusyResponseThread,
                                                                pHardwareContext,
                                                                0,
                                                                &busyThreadID);

    if (NULL == pHardwareContext->hControllerBusyResponseThread)
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }
#endif

    //driver not shutting down
    pHardwareContext->DriverShutdown = FALSE;

    // Initialize SDControllerIstThread() to handle interrupt generated by Host Controller
    DWORD threadID;                         
    // create the interrupt thread for controller interrupts
    pHardwareContext->hControllerInterruptThread = CreateThread(NULL,
                                                                0,
                                                                (LPTHREAD_START_ROUTINE)SDControllerIstThread,
                                                                pHardwareContext,
                                                                0,
                                                                &threadID);

    if (NULL == pHardwareContext->hControllerInterruptThread)
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    // Translate IRQ to SYSINTR
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &(pHardwareContext->dwIrqSDHC), 
                         sizeof(pHardwareContext->dwIrqSDHC), &(pHardwareContext->dwSysintrSDHC), 
                         sizeof(pHardwareContext->dwSysintrSDHC), NULL))
    {
        ERRORMSG(ZONE_ERROR,(TEXT("%s: Request SYSINTR failed\r\n"), __WFUNCTION__));
        goto exitInit;
    }

    //Initialize interrupt
    if (!InterruptInitialize(pHardwareContext->dwSysintrSDHC, 
                             pHardwareContext->hControllerInterruptEvent, NULL, 0))
    {
        ERRORMSG(ZONE_ERROR,(TEXT("%s: Interrupt initialization failed! \r\n"), __WFUNCTION__));
        goto exitInit;
    }


    exitInit:
    if (!SD_API_SUCCESS(status))
    {
        // just call the deinit handler directly to cleanup
        SDDeinitialize(pHCContext);
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-SDInitialize: Initialize the the MMC Controller\r\n")));
    return status;
}
//------------------------------------------------------------------------------
//
// Function: SDDeInitialize
//
// Deinitialize the the MMC Controller
//
// Parameters:
//       pHCContext[in] - Host controller context
//
// Returns:
//      SD_API_STATUS code
//
//------------------------------------------------------------------------------
SD_API_STATUS SDDeinitialize(PSDCARD_HC_CONTEXT pHCContext)
{
    PSDH_HARDWARE_CONTEXT pHardwareContext; // hardware context
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+SDDeinitialize: \r\n")));
    pHardwareContext = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

    // make sure all interrupt sources are disabled
    InterruptDisable(pHardwareContext->dwSysintrSDHC);

    // Indicate shutdown to threads
    pHardwareContext->DriverShutdown = TRUE;

    // clean up controller IST
    if (NULL != pHardwareContext->hControllerInterruptThread)
    {
        // wake up the IST
        SetEvent(pHardwareContext->hControllerInterruptEvent);
        CloseHandle(pHardwareContext->hControllerInterruptThread);
        pHardwareContext->hControllerInterruptThread = NULL;
    }

#ifdef SD_R1B_BUSYWAIT_WORKAROUND
     // clean up controller busy wait thread
    if (NULL != pHardwareContext->hControllerBusyResponseThread)
    {
        // wake up the busy wait thread
        SetEvent(pHardwareContext->hControllerBusyEvent);
        CloseHandle(pHardwareContext->hControllerBusyResponseThread);
        pHardwareContext->hControllerBusyResponseThread = NULL;
	// free controller interrupt event
    	if (NULL != pHardwareContext->hControllerBusyEvent)
    	{
            CloseHandle(pHardwareContext->hControllerBusyEvent);
            pHardwareContext->hControllerBusyEvent = NULL;
    	}
    }
#endif

    // clean up card detection IST and free card insertion interrupt
    CleanupCardPresenceDetect(pHardwareContext);

    // Release SYSINTR
    KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &(pHardwareContext->dwSysintrSDHC), 
                    sizeof(DWORD), NULL, 0, NULL);
    pHardwareContext->dwSysintrSDHC = SYSINTR_UNDEFINED;

    // free controller interrupt event
    if (NULL != pHardwareContext->hControllerInterruptEvent)
    {
        CloseHandle(pHardwareContext->hControllerInterruptEvent);
        pHardwareContext->hControllerInterruptEvent = NULL;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -