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

📄 sdhcslot.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                             )
{
    DEBUGCHK(VALID_DX(cpsNew));

    m_fIsPowerManaged = TRUE;

    if (DX_D1_OR_D2(cpsNew)) {
        cpsNew = D0;
    }

    if (m_cpsCurrent != cpsNew) {
        SetHardwarePowerState(cpsNew);
    }
}


VOID
CSDHCSlotBase::PowerDown(
                         )
{
    Validate();

    m_cpsAtPowerDown = m_cpsCurrent;

    if (!m_fIsPowerManaged) {
        CEDEVICE_POWER_STATE cps;

        if (m_bWakeupControl) {
            cps = D3;
        }
        else {
            cps = (_CEDEVICE_POWER_STATE)D4;
        }

        SetHardwarePowerState(cps);
    }

    BOOL fKeepPower = FALSE;
    if (m_fSleepsWithPower || m_cpsCurrent == D0) {
        DEBUGCHK(!m_fSleepsWithPower || m_cpsCurrent == D3);
        fKeepPower = TRUE;
    }

    PowerUpDown(FALSE, fKeepPower);
}


VOID
CSDHCSlotBase::PowerUp(
                       )
{
#ifdef NEW_POWER_MANAGEMENT
	DWORD waitResult;
#endif

    Validate();

    if (!m_fIsPowerManaged) {
        SetHardwarePowerState(m_cpsAtPowerDown);
    }
    else if (m_fSleepsWithPower) {
        WORD wIntStatus = ReadWord(SDHC_NORMAL_INT_STATUS);
        if (wIntStatus == NORMAL_INT_STATUS_CARD_INT) {
            // We woke system through a card interrupt. We need to clear
            // this so that the IST will not be signalled.
            EnableSDIOInterrupts(FALSE);
            m_fPowerUpDisabledInts = TRUE;
        }
    }

    PowerUpDown(TRUE, TRUE);
    Start();	// added by JJG 06.11.11

#ifdef NEW_POWER_MANAGEMENT
	// for wakeup problem. hsjang 070823
	RETAILMSG(1,(TEXT("[HSMMC] Waiting for finishing the initialization of card\r\n")));

	//waitResult = WaitForSingleObject(m_hWaitForEndofWakeup, INFINITE);
	waitResult = WaitForSingleObject(m_hWaitForEndofWakeup, 10000);
	if (WAIT_OBJECT_0 != waitResult )
		RETAILMSG(1,(TEXT("[HSMMC] Fail to restart due to something\r\n")));
	else
		RETAILMSG(1,(TEXT("[HSMMC] Finished the initialization of card\r\n")));	    
#endif
}


SD_API_STATUS
CSDHCSlotBase::BusRequestHandler(
                                 PSD_BUS_REQUEST pRequest
                                 )
{
    SETFNAME();

    PREFAST_DEBUGCHK(pRequest);
    Validate();

    WORD            wRegCommand;
    SD_API_STATUS   status;
    WORD            wIntStatusEn;
//2007.10.07 D.Baek
    WORD            wIntSignalEn;
    BOOL            fSuccess;

		
       WORD wErrIntSignalEn = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
       WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);

    	DEBUGCHK(m_dwReadyInts == 0);
    	DEBUGCHK(!m_fCommandCompleteOccurred);

    	RETAILMSG(0, (TEXT("%s CMD:%d\r\n"), pszFname, pRequest->CommandCode)); // jylee

    	DEBUGMSG(SDHC_SEND_ZONE, (TEXT("%s CMD:%d\r\n"), pszFname, pRequest->CommandCode));

    	// bypass CMD12 if AutoCMD12 was done by hardware
    	if (pRequest->CommandCode == 12) {
        	if (m_fAutoCMD12Success) {
            	RETAILMSG(CRC_DEBUG,(TEXT("%s AutoCMD12 Succeeded, bypass CMD12.\r\n"), pszFname));
            	DEBUGMSG(SDHC_SEND_ZONE, (TEXT("%s AutoCMD12 Succeeded, bypass CMD12.\r\n"), pszFname));
            	// The response for Auto CMD12 is in a special area
            	UNALIGNED DWORD *pdwResponseBuffer = (PDWORD) (pRequest->CommandResponse.ResponseBuffer + 1); // Skip CRC
            	*pdwResponseBuffer = ReadDword(SDHC_R6);
            	IndicateBusRequestComplete(pRequest, SD_API_STATUS_SUCCESS);
            	status = SD_API_STATUS_SUCCESS;
            	goto EXIT;
        	}
    	}

    	m_fAutoCMD12Success = FALSE;

#ifdef NEW_POWER_MANAGEMENT
    // for wakeup problem. hsjang 070823
    if ( m_fWhileWakeup && pRequest->CommandCode == 17)
    {
    	RETAILMSG(1,(TEXT("################# Release PM ###############\r\n")));
    	m_fWhileWakeup = FALSE;
    	SetEvent(m_hWaitForEndofWakeup);
    }   
#endif
    	// initialize command register with command code
    	RETAILMSG(0,(TEXT("SendCommand  0x%x\n"),pRequest->CommandCode));
    	wRegCommand = (pRequest->CommandCode << CMD_INDEX_SHIFT) & CMD_INDEX_MASK;

    	// check for a response
    	switch (pRequest->CommandResponse.ResponseType) {
    	case NoResponse:
        	break;

    	case ResponseR2:
        	wRegCommand |= CMD_RESPONSE_R2;
        	break;

    	case ResponseR3:
    	case ResponseR4:
        	wRegCommand |= CMD_RESPONSE_R3_R4;
        	break;

    	case ResponseR1:
    	case ResponseR5:
    	case ResponseR6:

#ifdef MMC_SPEC_40
/*************************************************************************/
/****** Date : 07.05.14                                         	******/
/****** Developer : HS.JANG											******/
/****** Description : to support SD SPEC20 card. Response7 is added	******/
/****** 			  for supporting SD SPEC20 card					******/
/*************************************************************************/
    	case ResponseR7:
/*************************************************************************/
#endif    
        	wRegCommand |= CMD_RESPONSE_R1_R5_R6;
        	break;

    	case ResponseR1b:

			wRegCommand |= CMD_RESPONSE_R1B_R5B;
		    break;
    	default:
        	status = SD_API_STATUS_INVALID_PARAMETER;
        	goto EXIT;
    	}

    // Set up variable for the new interrupt sources. Note that we must
    // enable DMA and read/write interrupts in this routine (not in
    // HandleCommandComplete) or they will be missed.
    wIntStatusEn = ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE);
    wIntStatusEn |= NORMAL_INT_ENABLE_CMD_COMPLETE | NORMAL_INT_ENABLE_TRX_COMPLETE;
//--------------------------------------------------------------------------------------
//2007.10.07 D.Baek
    wIntSignalEn = ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE);
    wIntSignalEn |= NORMAL_INT_ENABLE_CMD_COMPLETE | NORMAL_INT_ENABLE_TRX_COMPLETE;
//--------------------------------------------------------------------------------------
    // check command inhibit, wait until OK
    fSuccess = WaitForReg<DWORD>(&CSDHCSlotBase::ReadDword, SDHC_PRESENT_STATE, STATE_CMD_INHIBIT, 0);
    if (!fSuccess) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for CMD Inhibit\r\n"), pszFname));
        RETAILMSG(1, (TEXT("%s Timeout waiting for CMD Inhibit\r\n"), pszFname)); // jylee
        status = SD_API_STATUS_DEVICE_NOT_RESPONDING;
        goto EXIT;
    }

    // programming registers
    if (!TRANSFER_IS_COMMAND_ONLY(pRequest)) {
        WORD wRegTxnMode = 0;
 #ifdef MMC_SPEC_40
/*************************************************************************/
/****** Date : 07.05.14                                         	******/
/****** Developer : HS.JANG											******/
/****** Description : to support MMCmicro this code was added	 	******/
/*************************************************************************/
#if 1
	if((ReadByte(SDHC_TIMEOUT_CONTROL)!= m_dwTimeoutControl) && pRequest->CommandCode != MMC_CMD_SEND_EXT_CSD ) 
	{
		WriteByte(SDHC_TIMEOUT_CONTROL, (BYTE) m_dwTimeoutControl);
	}

    if(pRequest->CommandCode == MMC_CMD_SEND_EXT_CSD) 
	{
	    WriteByte(SDHC_TIMEOUT_CONTROL, 0x3);
	}
#endif
/*************************************************************************/
#endif
        wRegCommand |= CMD_DATA_PRESENT;

        if (UseDmaForRequest(pRequest)) {
            wIntStatusEn |= NORMAL_INT_ENABLE_DMA;
//2007.10.07 D.Baek
			wIntSignalEn |= NORMAL_INT_ENABLE_DMA;
            BOOL fNoException;
            DEBUGCHK(TRANSFER_SIZE(pRequest) <= CB_DMA_BUFFER);

            if (TRANSFER_IS_WRITE(pRequest)) {
                DWORD cbToTransfer = TRANSFER_SIZE(pRequest);

//                SD_SET_PROC_PERMISSIONS_FROM_REQUEST(pRequest) {
                    fNoException = SDPerformSafeCopy(m_pbDmaBuffer, pRequest->pBlockBuffer, cbToTransfer);
//                } SD_RESTORE_PROC_PERMISSIONS();

                if (fNoException == FALSE) {
                    status = SD_API_STATUS_ACCESS_VIOLATION;
                    goto EXIT;
                }
            }

            WriteDword(SDHC_SYSTEMADDRESS_LO, m_paDmaBuffer);
            wRegTxnMode |= TXN_MODE_DMA;
        }
        else {
            if (TRANSFER_IS_WRITE(pRequest)) {
                wIntStatusEn |= NORMAL_INT_ENABLE_BUF_WRITE_RDY;
            }
            else {
                wIntStatusEn |= NORMAL_INT_ENABLE_BUF_READ_RDY;
            }
        }

        // BlockSize
        // Note that for DMA we are programming the buffer boundary for 512K Bytes
        DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending command block size 0x%04X\r\n"), (WORD) pRequest->BlockSize));
        WriteWord(SDHC_BLOCKSIZE,  (WORD)((0x7<<12)| pRequest->BlockSize));
//        WriteWord(SDHC_BLOCKSIZE,  (WORD)((0x1<<12)| pRequest->BlockSize));
        // We always go into block mode even if there is only 1 block.
        // Otherwise the Pegasus will occaissionally hang when
        // writing a single block with DMA.
        wRegTxnMode |= (TXN_MODE_MULTI_BLOCK | TXN_MODE_BLOCK_COUNT_ENABLE);

#if 0  
		if(pRequest->CommandCode == 18 || pRequest->CommandCode == 25)
			 wRegTxnMode |= (TXN_MODE_MULTI_BLOCK | TXN_MODE_BLOCK_COUNT_ENABLE);
		else
			wRegTxnMode |= ( TXN_MODE_BLOCK_COUNT_ENABLE);
#endif

        // BlockCount
        DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending command block count 0x%04X\r\n"), (WORD) pRequest->NumBlocks));
        WriteWord(SDHC_BLOCKCOUNT, (WORD) pRequest->NumBlocks);

        if (pRequest->Flags & SD_AUTO_ISSUE_CMD12 && *((DWORD *)(pRequest->hDevice)) != 0 ) {
            wRegTxnMode |= TXN_MODE_AUTO_CMD12;
        }

        if (TRANSFER_IS_READ(pRequest)) {
            wRegTxnMode |= TXN_MODE_DATA_DIRECTION_READ;
        }

        // check dat inhibit, wait until okay
        fSuccess = WaitForReg<DWORD>(&CSDHCSlotBase::ReadDword, SDHC_PRESENT_STATE, STATE_DAT_INHIBIT, 0);
        if (!fSuccess) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for DAT Inhibit\r\n"), pszFname));
            RETAILMSG(CRC_DEBUG, (TEXT("%s Timeout waiting for DAT Inhibit\r\n"), pszFname)); // jylee
            status = SD_API_STATUS_DEVICE_NOT_RESPONDING;
            goto EXIT;
        }

        DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending Transfer Mode 0x%04X\r\n"),wRegTxnMode));
        WriteWord(SDHC_TRANSFERMODE, wRegTxnMode);
    }
    else {
		RETAILMSG(0,(TEXT("Command Only\n")));
        // Command-only
        if (pRequest->CommandCode == SD_CMD_STOP_TRANSMISSION) {
            wRegCommand |= CMD_TYPE_ABORT;
        }
        else if (TransferIsSDIOAbort(pRequest)) {
            // Use R5b For CMD52, Function 0, I/O Abort
            DEBUGMSG(SDHC_SEND_ZONE, (TEXT("Sending Abort command \r\n")));
            wRegCommand |= CMD_TYPE_ABORT | CMD_RESPONSE_R1B_R5B;
        }

	if (pRequest->CommandCode == 23) {
            wRegCommand |= CMD_INDEX_CHECK | CMD_CRC_CHECK | CMD_RESPONSE_LENGTH_48;
        }

        // The following is required for the Pegasus. If it is not present,
        // command-only transfers will sometimes fail (especially R1B and R5B).
//---------------------------------------------------------------------------------------
// 2007.09.12 D.Baek
// The "Data CRC Error" occurs if the following code will be inserted.
// Especially, it causes this type of error to write the "Block Size" register again.

        //WriteDword(SDHC_SYSTEMADDRESS_LO, 0);
        //WriteWord(SDHC_BLOCKSIZE, 0);
        //WriteWord(SDHC_BLOCKCOUNT, 0);
//---------------------------------------------------------------------------------------
    }

    DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending command register 0x%04X\r\n"),wRegCommand));
    DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending command Argument 0x%08X\r\n"),pRequest->CommandArgument));

    WriteDword(SDHC_ARGUMENT_0, pRequest->CommandArgument);

    // Enable transfer interrupt sources.
    WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, wIntStatusEn);
//---------------------------------------------------------------------------------------
//2007.10.07 D.Baek
    WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, wIntSignalEn);
//---------------------------------------------------------------------------------------
    // Turn the clock on. It is turned off in IndicateBusRequestComplete().
    RETAILMSG(0,(TEXT("[BusRequestHandler]SDHC_CLOCK_CONTROL : 0x%x\r\n"),ReadWord(SDHC_CLOCK_CONTROL)));
    
    SDClockOn();

⌨️ 快捷键说明

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