📄 sdcontrol.cpp
字号:
}
} else
status = SD_API_STATUS_INVALID_PARAMETER;
break;
case SDHCDQueryBlockCapability:
if (pData && OptionSize == sizeof(SD_HOST_BLOCK_CAPABILITY))
{
pBlockCaps = (PSD_HOST_BLOCK_CAPABILITY)pData;
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler: Read Block Length: %d , Read Blocks: %d\r\n"),
pBlockCaps->ReadBlockSize,
pBlockCaps->ReadBlocks));
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler: Write Block Length: %d , Write Blocks: %d\r\n"),
pBlockCaps->WriteBlockSize,
pBlockCaps->WriteBlocks));
if (pBlockCaps->ReadBlockSize > SDH_MAX_BLOCK_SIZE)
{
pBlockCaps->ReadBlockSize = SDH_MAX_BLOCK_SIZE;
}
if (pBlockCaps->ReadBlockSize < SDH_MIN_BLOCK_SIZE )
{
pBlockCaps->ReadBlockSize = SDH_MIN_BLOCK_SIZE;
}
if (pBlockCaps->WriteBlockSize > SDH_MAX_BLOCK_SIZE)
{
pBlockCaps->WriteBlockSize = SDH_MAX_BLOCK_SIZE;
}
if (pBlockCaps->WriteBlockSize < SDH_MIN_BLOCK_SIZE )
{
pBlockCaps->WriteBlockSize = SDH_MIN_BLOCK_SIZE;
}
// ARM11 is limited by DMA buffer size allocated for MMCSD
pBlockCaps->ReadBlocks = SDHC_MAX_NUM_BLOCKS;
pBlockCaps->WriteBlocks = SDHC_MAX_NUM_BLOCKS;
} else
status = SD_API_STATUS_INVALID_PARAMETER;
break;
case SDHCDGetSlotInfo:
DEBUGMSG(ZONE_INFO,
(TEXT("SDHSlotOptionHandler - called - SDHCDGetSlotInfo \r\n")));
if ( OptionSize != sizeof(SDCARD_HC_SLOT_INFO) || pData == NULL )
{
status = SD_API_STATUS_INVALID_PARAMETER;
} else
{
PSDCARD_HC_SLOT_INFO pSlotInfo = (PSDCARD_HC_SLOT_INFO)pData;
// set the slot capabilities
SDHCDSetSlotCapabilities(pSlotInfo, SD_SLOT_SD_1BIT_CAPABLE |
SD_SLOT_SD_4BIT_CAPABLE |
SD_SLOT_SDIO_CAPABLE |
SD_SLOT_SDMEM_4BIT_CAPABLE |
SD_SLOT_SDIO_INT_DETECT_4BIT_MULTI_BLOCK);
//TODO: Set all valid masks.
//TODO: PMIC do not support ranges >3.00V.
//Set Slot voltage window
pController->dwVoltageWindowMask = (SD_VDD_WINDOW_2_9_TO_3_0 |
SD_VDD_WINDOW_3_0_TO_3_1 |
SD_VDD_WINDOW_3_1_TO_3_2);
SDHCDSetVoltageWindowMask(pSlotInfo, pController->dwVoltageWindowMask);
// Set optimal voltage
//TODO : is this range supported
pController->dwOptVoltageMask = SLOT_VOLTAGE_MAX_BITMASK;
SDHCDSetDesiredSlotVoltage(pSlotInfo, pController->dwOptVoltageMask);
// Controller may be able to clock at higher than the max SD rate,
// but we should only report the highest rate in the range.
DWORD dwMaxClockRateInSDRange = SD_FULL_SPEED_RATE;
SetRate(pController, &dwMaxClockRateInSDRange, FALSE);
SDHCDSetMaxClockRate(pSlotInfo, dwMaxClockRateInSDRange);
// Set power up delay.
pController->dwPowerUpDelay = SDHC_MAX_POWER_SUPPLY_RAMP_UP;
SDHCDSetPowerUpDelay(pSlotInfo, pController->dwPowerUpDelay);
}
break;
default:
status = SD_API_STATUS_INVALID_PARAMETER;
break;
}
return status;
}
//------------------------------------------------------------------------------
//
// Function: SDPowerUp
//
// Power up handler. To be called within XXX_PowerOn only
//
// Parameters:
// pHostContext[in] - host controller context
//
// Returns:
// none
//
//------------------------------------------------------------------------------
void SDPowerUp(PSDCARD_HC_CONTEXT pHCContext)
{
PSDH_HARDWARE_CONTEXT pHCDevice;
DEBUGMSG(ZONE_FUNCTION, (TEXT("SDPowerUp+\r\n")));
pHCDevice = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);
SetHardwarePowerState(pHCDevice, pHCDevice->PsAtPowerDown);
//Since 1 controller support 1 SD slot, we use index 0
SDHCDPowerUpDown(pHCContext, TRUE, TRUE, 0);
DEBUGMSG(ZONE_FUNCTION, (TEXT("SDPowerUp-\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: SDPowerDown
//
// Power down handler. To be called within XXX_PowerDown only
//
// Parameters:
// pHostContext[in] - host controller context
//
// Returns:
// none
//
//------------------------------------------------------------------------------
void SDPowerDown(PSDCARD_HC_CONTEXT pHCContext)
{
PSDH_HARDWARE_CONTEXT pHCDevice;
CEDEVICE_POWER_STATE cps;
DEBUGMSG(ZONE_FUNCTION, (TEXT("SDPowerDown+\r\n")));
// Do not allow client driver to continue submit request during power down.
//Since 1 controller support 1 SD slot, we use index 0
SDHCDPowerUpDown(pHCContext, FALSE, FALSE, 0);
pHCDevice = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);
pHCDevice->PsAtPowerDown = pHCDevice->CurrentPowerState;
if (pHCDevice->fWakeOnSDIOInt)
{
cps = D3;
} else
{
cps = D4;
}
SetHardwarePowerState(pHCDevice, cps);
DEBUGMSG(ZONE_FUNCTION, (TEXT("SDPowerDown-\r\n")));
}
/*******************************************************************************
PRIVATE FUNCTIONS
*******************************************************************************/
#ifdef SD_R1B_BUSYWAIT_WORKAROUND
//------------------------------------------------------------------------------
//
// Function: SDControllerBusyResponseThread
//
// Thread for SDHC/MMC Controller driver which busy waits for controller to be ready
// in order to invoke next commands
//
// Parameters:
// pHCDevice[in] - the controller instance
//
// Returns:
// Thread exit code
//
//------------------------------------------------------------------------------
DWORD SDControllerBusyResponseThread(PSDH_HARDWARE_CONTEXT pHCDevice)
{
DWORD cmdatRegister=0, cmdArg = 0; // CMDAT register
PSD_BUS_REQUEST pRequest;
SD_API_STATUS status = SD_API_STATUS_SUCCESS;
LONG ii; // loop variable
USHORT responseBuffer[SDH_RESPONSE_FIFO_DEPTH - 5]; // response buffer
SD_CARD_STATUS CardStatus = 0, CardState = 0;
PUCHAR tempBuffer = NULL;
CHAR retryCount =0;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+SDControllerBusyResponseThread: Thread for SDHC/MMC Controller driver\r\n")));
#if !VPMX31
//cant use with virtio. It will cause thread synchronization problem
if (!CeSetThreadPriority(GetCurrentThread(), (pHCDevice->ControllerIstThreadPriority + 2)))
{
ERRORMSG(ZONE_ERROR, (TEXT("SDControllerBusyResponseThread: warning, failed to set CEThreadPriority \n")));
}
#endif //VPMX31
while (1)
{
DEBUGMSG(ZONE_INFO, (TEXT("SDControllerBusyResponseThread:Wait For Signal ... \r\n")));
if (WaitForSingleObject(pHCDevice->hControllerBusyEvent, INFINITE) != WAIT_OBJECT_0)
{
// bail out
ERRORMSG(ZONE_ERROR, (TEXT("SDControllerBusyResponseThread: Wait Failed! \r\n")));
return 0;
}
if (pHCDevice->DriverShutdown)
{
DEBUGMSG(ZONE_INFO, (TEXT("SDControllerBusyResponseThread: Thread Exiting\r\n")));
return 0;
}
retryCount = DEFAULT_BUS_REQUEST_RETRY_COUNT;
pRequest = SDHCDGetAndLockCurrentRequest(pHCDevice->pHCContext, 0);
cmdArg = (((DWORD)((SDDCGetClientDeviceFromHandle(pRequest->hDevice))->RelativeAddress)) << 16);
do
{
status = SD_API_STATUS_SUCCESS;
if (CardState != CardStatus)
{
DEBUGMSG (ZONE_INFO,(TEXT("SDControllerBusyResponseThread: Sleeping before issuing next Status cmd\r\n")));
Sleep (0);
}
CardState = CardStatus;
DEBUGMSG(ZONE_INFO, (TEXT("SDControllerBusyResponseThread: Sending Status Command %d\r\n"), retryCount));
CardState = SD_STATUS_CURRENT_STATE_TRAN;
CSP_BITFINS(cmdatRegister, SDHC_CDC_FORMAT, 1);
// check to see if we need to enable wide bus (4 bit) data transfer mode
CSP_BITFINS(cmdatRegister, SDHC_CDC_BW, pHCDevice->BusWidthSetting);
// clear all status
OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, 0xFFFFFFFF);
// set the command
INSREG32BF(&pHCDevice->pSDMMCRegisters->CMD, SDHC_CMD_CMD, SD_CMD_SEND_STATUS);
// set the argument
INSREG32BF(&pHCDevice->pSDMMCRegisters->ARG, SDHC_ARG_ARG, cmdArg);
// write the CMDAT register
OUTREG32(&pHCDevice->pSDMMCRegisters->CMD_DAT_CONT, cmdatRegister);
//start clock
SetClock(pHCDevice, TRUE);
while (!EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_ECR))
Sleep (0);
// Clear interrupt status by writing 1 to the corresponsing bit only
OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_ECR, 1));
//Check for response time-out or crc error.If found, retry again
if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_TORESP))
{
// Clear status by writing 1
OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_TORESP, 1));
retryCount --;
status = SD_API_STATUS_RESPONSE_TIMEOUT;
ERRORMSG(ZONE_ERROR, (TEXT("SDControllerBusyResponseThread: Status Command timeout\r\n")));
continue;
}
if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_RSPCERR))
{
// Clear status by writing 1
OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_RSPCERR, 1));
retryCount --;
status = SD_API_STATUS_CRC_ERROR;
ERRORMSG(ZONE_ERROR, (TEXT("SDControllerBusyResponseThread: response CRC error\r\n")));
continue;
}
memset ((&responseBuffer), 0, (SDH_RESPONSE_FIFO_DEPTH - 5));
// read in the response words from the response fifo.
for (ii = 2; ii >= 0; ii--)
{
// read from the fifo
responseBuffer[ii] =INREG16(&pHCDevice->pSDMMCRegisters->RES_FIFO);
DEBUGMSG(ZONE_INFO, (TEXT("responseBuffer[%d]=0x%x\r\n"),ii,responseBuffer[ii]));
}
tempBuffer = (PUCHAR)responseBuffer;
memcpy((&CardStatus), &tempBuffer[1], sizeof(SD_CARD_STATUS));
DEBUGMSG(ZONE_INFO, (TEXT("CardStatus=0x%x\r\n"),SD_STATUS_CURRENT_STATE(CardStatus)));
}while ( (SD_STATUS_CURRENT_STATE (CardStatus) != CardState) && (retryCount > 0) );
IndicateBusRequestComplete(pHCDevice, pRequest, status);
CardStatus = CardState = 0;
}
}
#endif
//------------------------------------------------------------------------------
//
// Function: SDControllerIstThread
//
// IST thread for MMC Controller driver
//
// Parameters:
// pHCDevice[in] - the controller instance
//
// Returns:
// Thread exit code
//
//------------------------------------------------------------------------------
DWORD SDControllerIstThread(PSDH_HARDWARE_CONTEXT pHCDevice)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("+SDControllerIstThread: IST thread for MMC Controller driver\r\n")));
#if !VPMX31
//cant use with virtio. It will cause thread synchronization problem
if (!CeSetThreadPriority(GetCurrentThread(), pHCDevice->ControllerIstThreadPriority))
{
ERRORMSG(ZONE_ERROR, (TEXT("SDControllerIstThread: warning, failed to set CEThreadPriority \n")));
}
#endif //VPMX31
while (1)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -