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

📄 sdhcslot.h

📁 Samsung公司S3C6400芯片的BSP源码包
💻 H
字号:
//
// 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) 2002 BSQUARE Corporation.  All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE

#ifndef _SDHCSLOT_DEFINED
#define _SDHCSLOT_DEFINED

#include "SDCardDDK.h"
#include <SDHCD.h>
#include <ceddk.h>
#include "SDHCRegs.h"


#define SDHC_MAX_POWER_SUPPLY_RAMP_UP   250     // SD Phys Layer 6.6

#define SDHC_POWER_UP_DELAY_KEY         _T("PowerUpDelay")
#define SDHC_WAKEUP_SOURCES_KEY         _T("DefaultWakeupSources")
#define SDHC_CAN_WAKE_ON_INT_KEY        _T("AllowWakeOnSDIOInterrupts")
#define SDHC_FREQUENCY_KEY              _T("BaseClockFrequency")
#define SDHC_TIMEOUT_FREQUENCY_KEY      _T("TimeoutClockFrequency")
#define SDHC_TIMEOUT_KEY                _T("TimeoutInMS")

#define CRC_DEBUG 0

typedef class CSDHCSlotBase {
public:
    // Constructor - only initializes the member data. True initialization
    // occurs in Init().
    CSDHCSlotBase();
    virtual ~CSDHCSlotBase();

    // Perform basic initialization including initializing the hardware
    // so that the capabilities register can be read.
    virtual BOOL Init(DWORD dwSlot, volatile BYTE *pbRegisters,
        PSDCARD_HC_CONTEXT pHCDContext, DWORD dwSysIntr, HANDLE hBusAccess,
        INTERFACE_TYPE interfaceType, DWORD dwBusNumber, CReg *pregDevice);

    // Second stage of hardware initialization. Complete slot configuration
    // and enable interrupts.
    virtual SD_API_STATUS Start();
    // Signals card removal disables the slot.
    virtual SD_API_STATUS Stop();

    // Process a slot option call.
    virtual SD_API_STATUS SlotOptionHandler(SD_SLOT_OPTION_CODE sdOption, 
        PVOID pData, DWORD cbData);

    // Get this slot's power state.
    virtual CEDEVICE_POWER_STATE GetPowerState() { return m_cpsCurrent; }

    // What power state is required upon power up?
    virtual CEDEVICE_POWER_STATE GetPowerUpRequirement() { return m_cpsAtPowerDown; }

    // Called when the device is suspending.
    virtual VOID PowerDown();
    // Called when the device is resuming.
    virtual VOID PowerUp();

    // Start this bus request.
    virtual SD_API_STATUS BusRequestHandler(PSD_BUS_REQUEST pRequest);

    // Returns TRUE if the interrupt routine needs servicing, say at
    // initialization to see if a card is present.
    virtual BOOL NeedsServicing() { return m_fCheckSlot; }

    // Handle a slot interrupt. Also called when NeedsServicing() returns TRUE.
    virtual VOID HandleInterrupt();

    BOOL IsOnlySDIOInterrupt();

    // Called by the controller to get the controller interrupt register.
    inline WORD ReadControllerInterrupts() {
        return ReadWord(SDHC_NORMAL_INT_STATUS);
    }



protected:
    // What is this slot's maximum clock rate?
    virtual DWORD DetermineMaxClockRate();

    // What is this slot's maximum block length?
    virtual DWORD DetermineMaxBlockLen();

    // What should this slot use for timeout control?
    virtual DWORD DetermineTimeoutControl();

    // What are the default wakeup sources?
    virtual DWORD DetermineWakeupSources();
    
    // Set the slot voltage.
    virtual VOID SetVoltage(DWORD dwVddSetting);
    // Set the bus width and clock rate.
    virtual VOID SetInterface(PSD_CARD_INTERFACE pInterface);

    // Set this slot's power state.
    virtual VOID SetPowerState(CEDEVICE_POWER_STATE cpsNew);

    // Get the capabilities register.
    virtual SSDHC_CAPABILITIES GetCapabilities() {
        SSDHC_CAPABILITIES caps;
        caps.dw = ReadDword(SDHC_CAPABILITIES);
        return caps;
    }

    // Fill in the slot info structure.
    virtual SD_API_STATUS GetSlotInfo(PSDCARD_HC_SLOT_INFO pSlotInfo);

    // Get the desired Vdd window.
    virtual DWORD GetDesiredVddWindow();

    // Get the max Vdd window.
    virtual DWORD GetMaxVddWindow();

    // Is the card write-protected?
    virtual BOOL IsWriteProtected() {
        return ((ReadDword(SDHC_PRESENT_STATE) & STATE_WRITE_PROTECT) == STATE_WRITE_PROTECT);
    }

    // Enable/disable SDIO card interrupts.
    virtual VOID EnableSDIOInterrupts(BOOL fEnable);

    // How much extra time in ms for initial clocks is needed upon
    // insertion of a card for the power supply ramp up?
    virtual DWORD GetPowerSupplyRampUpMs() {
        return m_pregDevice->ValueDW(SDHC_POWER_UP_DELAY_KEY,
            SDHC_MAX_POWER_SUPPLY_RAMP_UP);
    }
    
    // Register access routines. These are not virtual so that we get
    // good inline read/write perf.
    template <class T>
    inline VOID WriteReg   (DWORD dwOffset, T tValue) {
        CheckRegOffset(dwOffset, sizeof(T));
        volatile T *ptRegister = (volatile T *) (m_pbRegisters + dwOffset);
        *ptRegister = tValue;
    }
    template <class T>
    inline T ReadReg       (DWORD dwOffset) {
        CheckRegOffset(dwOffset, sizeof(T));
        volatile T *ptRegister = (volatile T *) (m_pbRegisters + dwOffset);
        return *ptRegister;
    }

    inline BYTE  ReadByte  (DWORD dwOffset) {
        return ReadReg<BYTE>(dwOffset);
    }
    inline VOID  WriteByte (DWORD dwOffset, BYTE bValue) {
        WriteReg(dwOffset, bValue);
    }

    inline WORD  ReadWord  (DWORD dwOffset) {
        return ReadReg<WORD>(dwOffset);
    }
    inline VOID  WriteWord (DWORD dwOffset, WORD wValue) {
        WriteReg(dwOffset, wValue);
    }

    inline DWORD ReadDword (DWORD dwOffset) {
        return ReadReg<DWORD>(dwOffset);
    }
    inline VOID  WriteDword(DWORD dwOffset, DWORD dwValue) {
        WriteReg(dwOffset, dwValue);
    }


    // Interrupt handling methods
    virtual VOID HandleRemoval(BOOL fCancelRequest);
    virtual VOID HandleInsertion();
    virtual BOOL HandleCommandComplete();
    virtual VOID HandleErrors();
    virtual VOID HandleTransferDone();
    virtual VOID HandleReadReady();
    virtual VOID HandleWriteReady();
    virtual VOID HandleDma();    

    // Determines if DMA can be used for this request taking alignment
    // requirements and capabilities into account.
    virtual BOOL UseDmaForRequest(PSD_BUS_REQUEST pRequest);

    // Allocates a physical buffer for DMA.
    virtual PVOID AllocPhysBuffer(size_t cb, PDWORD pdwPhysAddr);

    // Frees the physical buffer.
    virtual VOID FreePhysBuffer(PVOID pv);

    // Place the slot into the desired power state.
    virtual VOID SetHardwarePowerState(CEDEVICE_POWER_STATE cpsNew);

    // Performs the actual enabling/disabling of SDIO card interrupts.
    virtual VOID DoEnableSDIOInterrupts(BOOL fEnable);

    // Perform the desired reset and wait for completion. Returns FALSE
    // if there is a timeout.
    virtual BOOL SoftwareReset(BYTE bResetBits);

    // Keep reading the register using (*pfnReadReg)(dwRegOffset) until
    // value & tMask == tWaitForEqual.
    template<class T>
    BOOL WaitForReg(
        T (CSDHCSlotBase::*pfnReadReg)(DWORD),
        DWORD dwRegOffset,
        T tMask,
        T tWaitForEqual,
        DWORD dwTimeout = 1000        
        );

    // Turn the LED on or off.
    virtual VOID EnableLED(BOOL fEnable);

    // Calls SDHCDIndicateSlotStateChange.
    virtual VOID IndicateSlotStateChange(SD_SLOT_EVENT sdEvent);

    // Calls SDHCDGetAndLockCurrentRequest.
    virtual PSD_BUS_REQUEST GetAndLockCurrentRequest();

    // Calls SDHCDPowerUpDown.
    virtual VOID PowerUpDown(BOOL fPowerUp, BOOL fKeepPower);

    // Calls SDHCDIndicateBusRequestComplete.
    virtual VOID IndicateBusRequestComplete(PSD_BUS_REQUEST pRequest, SD_API_STATUS status);

    // Finds the closest rate that is *pdwRate or lower. Stores the
    // actual rate in *pdwRate.
    virtual VOID SetClockRate(PDWORD pdwRate);

    // Turn on the SD clock according to the clock divisor found 
    // in SetClockRate().
    virtual VOID SDClockOn();

    // Turn off the SD clock.
    virtual VOID SDClockOff();

    // Determine the Vdd windows from the capabilities register.
    virtual DWORD DetermineVddWindows();

    // Set an interrupt event.
    virtual VOID SetInterruptEvent() { ::SetInterruptEvent(m_dwSysIntr); }


#ifdef DEBUG
    // Print out the standard host register set.
    virtual VOID DumpRegisters();

    // Validate the member data.
    virtual VOID Validate();

    // Verify that the desired register accesses are properly aligned.
    VOID CheckRegOffset(DWORD dwOffset, DWORD dwRegSize) {
        DEBUGCHK( (dwOffset % dwRegSize) == 0);
        DEBUGCHK(dwOffset < sizeof(SSDHC_REGISTERS));
        DEBUGCHK( (dwOffset + dwRegSize) <= sizeof(SSDHC_REGISTERS));
    }
#else
    // These routines do nothing in non-debug builds.
    inline VOID DumpRegisters() {}
    inline VOID Validate() {}
    inline VOID CheckRegOffset(DWORD dwOffset, DWORD dwRegSize) {}
#endif

    CReg                   *m_pregDevice;           // pointer to device registry key
    DWORD                   m_dwSlot;               // physical slot number
    volatile BYTE          *m_pbRegisters;          // memory-mapped registers

    PSDCARD_HC_CONTEXT      m_pHCDContext;          // host context
    DWORD                   m_dwSysIntr;            // system interrupt
    HANDLE                  m_hBusAccess;           // bus parent
    INTERFACE_TYPE          m_interfaceType;        // interface of the controller
    DWORD                   m_dwBusNumber;          // bus number of the controller

    DWORD                   m_dwVddWindows;         // supported VDD windows
    DWORD                   m_dwMaxClockRate;       // maximum clock rate
    DWORD                   m_dwTimeoutControl;     // timeout control value
    DWORD                   m_dwMaxBlockLen;        // maximum block length

    PBYTE                   m_pbDmaBuffer;          // virtual address of DMA buffer
    DWORD                   m_paDmaBuffer;          // physical address of DMA buffer

    WORD                    m_wRegClockControl;     // register value of Clock Control
    WORD                    m_wIntSignals;          // saved int signals for powerup
    CEDEVICE_POWER_STATE    m_cpsCurrent;           // current power state
    CEDEVICE_POWER_STATE    m_cpsAtPowerDown;       // power state at PowerDown()

    DWORD                   m_dwDefaultWakeupControl;   // wakeup source list 
    BYTE                    m_bWakeupControl;           // current wakeup interrupts

	BOOL		isSDIOInterrupt;

#ifdef DEBUG
    DWORD                   m_dwReadyInts;          // number of Read/WriteReady interrupts that have occurred
#endif DEBUG

    BOOL                    m_fCommandCompleteOccurred;     // has the Command Complete occurred for the current transfer?

    BOOL                    m_fSleepsWithPower : 1;         // keep power in PowerDown()?
    BOOL                    m_fPowerUpDisabledInts : 1;     // did PowerUp disable SDIO card interrupts?
    BOOL                    m_fIsPowerManaged : 1;          // is the power manager handling us?
    BOOL                    m_fSDIOInterruptsEnabled : 1;   // are SDIO card interrupts enabled?
    BOOL                    m_fCardPresent : 1;             // is a card present
    BOOL                    m_fAutoCMD12Success : 1;        // AutoCMD12 success
    BOOL                    m_fCheckSlot : 1;               // does HandleInterrupt() need to be run?
    BOOL                    m_fCanWakeOnSDIOInterrupts : 1; // can wake on SDIO interrupts
    BOOL                    m_f4BitMode : 1;                // 4 bit bus mode?
    BOOL                    m_fFakeCardRemoval : 1;         // should we simulate card removal?    
#ifdef NEW_POWER_MANAGEMENT
// 2007.08.29 D.Baek
// Sleep/Wakeup Support 
    BOOL                    m_fWhileWakeup : 1;             // dose it initialze a card after wakeup? 070822 hsjang
    HANDLE                  m_hWaitForEndofWakeup;
#endif     
} *PCSDHCSlotBase;


#define CB_DMA_BUFFER 0x30000 // 512KB buffer        0x20000//128KB buffer
#define CB_DMA_PAGE   0x30000 //  we program DMA for 512KB pages  // 0x1000  // we program DMA for 4KB pages


#define TRANSFER_IS_WRITE(pRequest)        (SD_WRITE == (pRequest)->TransferClass)
#define TRANSFER_IS_READ(pRequest)         (SD_READ == (pRequest)->TransferClass)
#define TRANSFER_IS_COMMAND_ONLY(pRequest) (SD_COMMAND == (pRequest)->TransferClass)      

#define TRANSFER_SIZE(pRequest)            ((pRequest)->BlockSize * (pRequest)->NumBlocks)


#define SDHC_DEFAULT_TIMEOUT                2000 // 2 seconds


// Is this request an SDIO abort (CMD52, Function 0, I/O Abort Reg)?
inline
BOOL
TransferIsSDIOAbort(
                    PSD_BUS_REQUEST pRequest
                    )
{
    PREFAST_DEBUGCHK(pRequest);

    BOOL fRet = FALSE;
    
    if (pRequest->CommandCode == SD_CMD_IO_RW_DIRECT) {
        if (IO_RW_DIRECT_ARG_FUNC(pRequest->CommandArgument) == 0) {
            if (IO_RW_DIRECT_ARG_ADDR(pRequest->CommandArgument) == SD_IO_REG_IO_ABORT) {
                fRet = TRUE;
            }
        }
    }

    return fRet;
}

#endif // _SDHCSLOT_DEFINED

// DO NOT REMOVE --- END EXTERNALLY DEVELOPED SOURCE CODE ID --- DO NOT REMOVE

⌨️ 快捷键说明

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