sdmmc: use m_ for member variables
This commit is contained in:
@@ -247,22 +247,22 @@ namespace ams::sdmmc::impl {
|
||||
this->SetSchmittTrigger(bus_power);
|
||||
|
||||
/* Select one-cycle delay version of cmd_oen. */
|
||||
reg::ReadWrite(this->sdmmc_registers->io_spare, SD_REG_BITS_ENUM(IO_SPARE_SPARE_OUT_3, ONE_CYCLE_DELAY));
|
||||
reg::ReadWrite(m_sdmmc_registers->io_spare, SD_REG_BITS_ENUM(IO_SPARE_SPARE_OUT_3, ONE_CYCLE_DELAY));
|
||||
|
||||
/* Select regulated reference voltage for trimmer and DLL supply. */
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_io_trim_cntrl, SD_REG_BITS_VALUE(VENDOR_IO_TRIM_CNTRL_SEL_VREG, 0));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_io_trim_cntrl, SD_REG_BITS_VALUE(VENDOR_IO_TRIM_CNTRL_SEL_VREG, 0));
|
||||
|
||||
/* Configure outbound tap value. */
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_clock_cntrl, SD_REG_BITS_VALUE(VENDOR_CLOCK_CNTRL_TRIM_VAL, this->GetOutboundTapValue()));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_clock_cntrl, SD_REG_BITS_VALUE(VENDOR_CLOCK_CNTRL_TRIM_VAL, this->GetOutboundTapValue()));
|
||||
|
||||
/* Configure SPI_MODE_CLKEN_OVERRIDE. */
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_clock_cntrl, SD_REG_BITS_ENUM(VENDOR_CLOCK_CNTRL_SPI_MODE_CLKEN_OVERRIDE, NORMAL));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_clock_cntrl, SD_REG_BITS_ENUM(VENDOR_CLOCK_CNTRL_SPI_MODE_CLKEN_OVERRIDE, NORMAL));
|
||||
|
||||
/* Set slew codes. */
|
||||
this->SetSlewCodes();
|
||||
|
||||
/* Set vref sel. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sdmemcomppadctrl, SD_REG_BITS_VALUE(SDMEMCOMPPADCTRL_SDMMC2TMC_CFG_SDMEMCOMP_VREF_SEL, this->GetVrefSelValue()));
|
||||
reg::ReadWrite(m_sdmmc_registers->sdmemcomppadctrl, SD_REG_BITS_VALUE(SDMEMCOMPPADCTRL_SDMMC2TMC_CFG_SDMEMCOMP_VREF_SEL, this->GetVrefSelValue()));
|
||||
|
||||
/* Perform drive strength calibration at the new power. */
|
||||
this->SetDriveCodeOffsets(bus_power);
|
||||
@@ -277,14 +277,14 @@ namespace ams::sdmmc::impl {
|
||||
Result SdmmcController::SetClockTrimmer(SpeedMode speed_mode, u8 tap_value) {
|
||||
/* If speed mode is Hs400, set the dqs trim value. */
|
||||
if (speed_mode == SpeedMode_MmcHs400) {
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_cap_overrides, SD_REG_BITS_VALUE(VENDOR_CAP_OVERRIDES_DQS_TRIM_VAL, 40));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_cap_overrides, SD_REG_BITS_VALUE(VENDOR_CAP_OVERRIDES_DQS_TRIM_VAL, 40));
|
||||
}
|
||||
|
||||
/* Configure tap value as updated by software. */
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_tuning_cntrl0, SD_REG_BITS_ENUM(VENDOR_TUNING_CNTRL0_TAP_VALUE_UPDATED_BY_HW, NOT_UPDATED_BY_HW));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_tuning_cntrl0, SD_REG_BITS_ENUM(VENDOR_TUNING_CNTRL0_TAP_VALUE_UPDATED_BY_HW, NOT_UPDATED_BY_HW));
|
||||
|
||||
/* Set the inbound tap value. */
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_clock_cntrl, SD_REG_BITS_VALUE(VENDOR_CLOCK_CNTRL_TAP_VAL, tap_value));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_clock_cntrl, SD_REG_BITS_VALUE(VENDOR_CLOCK_CNTRL_TAP_VAL, tap_value));
|
||||
|
||||
/* Reset the cmd/dat line. */
|
||||
R_TRY(SdHostStandardController::ResetCmdDatLine());
|
||||
@@ -293,29 +293,29 @@ namespace ams::sdmmc::impl {
|
||||
}
|
||||
|
||||
u8 SdmmcController::GetCurrentTapValue() {
|
||||
return static_cast<u8>(reg::GetValue(this->sdmmc_registers->vendor_clock_cntrl, SD_REG_BITS_MASK(VENDOR_CLOCK_CNTRL_TAP_VAL)));
|
||||
return static_cast<u8>(reg::GetValue(m_sdmmc_registers->vendor_clock_cntrl, SD_REG_BITS_MASK(VENDOR_CLOCK_CNTRL_TAP_VAL)));
|
||||
}
|
||||
|
||||
Result SdmmcController::CalibrateDll() {
|
||||
/* Check if we need to temporarily re-enable the device clock. */
|
||||
const bool clock_disabled = reg::HasValue(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE));
|
||||
const bool clock_disabled = reg::HasValue(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE));
|
||||
|
||||
/* Ensure that the clock is enabled for the period we're using it. */
|
||||
if (clock_disabled) {
|
||||
/* Turn on the clock. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
}
|
||||
ON_SCOPE_EXIT { if (clock_disabled) { reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE)); } };
|
||||
ON_SCOPE_EXIT { if (clock_disabled) { reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE)); } };
|
||||
|
||||
/* Begin calibration. */
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_dllcal_cfg, SD_REG_BITS_ENUM(VENDOR_DLLCAL_CFG_CALIBRATE, ENABLE));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_dllcal_cfg, SD_REG_BITS_ENUM(VENDOR_DLLCAL_CFG_CALIBRATE, ENABLE));
|
||||
|
||||
/* Wait up to 5ms for calibration to begin. */
|
||||
{
|
||||
ManualTimer timer(5);
|
||||
while (true) {
|
||||
/* If calibration is done, we're done. */
|
||||
if (!reg::HasValue(this->sdmmc_registers->vendor_dllcal_cfg, SD_REG_BITS_ENUM(VENDOR_DLLCAL_CFG_CALIBRATE, ENABLE))) {
|
||||
if (!reg::HasValue(m_sdmmc_registers->vendor_dllcal_cfg, SD_REG_BITS_ENUM(VENDOR_DLLCAL_CFG_CALIBRATE, ENABLE))) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ namespace ams::sdmmc::impl {
|
||||
ManualTimer timer(10);
|
||||
while (true) {
|
||||
/* If calibration is done, we're done. */
|
||||
if (reg::HasValue(this->sdmmc_registers->vendor_dllcal_cfg_sta, SD_REG_BITS_ENUM(VENDOR_DLLCAL_CFG_STA_DLL_CAL_ACTIVE, DONE))) {
|
||||
if (reg::HasValue(m_sdmmc_registers->vendor_dllcal_cfg_sta, SD_REG_BITS_ENUM(VENDOR_DLLCAL_CFG_STA_DLL_CAL_ACTIVE, DONE))) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -343,12 +343,12 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
Result SdmmcController::SetSpeedModeWithTapValue(SpeedMode speed_mode, u8 tap_value) {
|
||||
/* Check if we need to temporarily disable the device clock. */
|
||||
const bool clock_enabled = reg::HasValue(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
const bool clock_enabled = reg::HasValue(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
|
||||
/* Ensure that the clock is disabled for the period we're using it. */
|
||||
if (clock_enabled) {
|
||||
/* Turn off the clock. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE));
|
||||
}
|
||||
|
||||
/* Set clock trimmer. */
|
||||
@@ -362,37 +362,37 @@ namespace ams::sdmmc::impl {
|
||||
case SpeedMode_MmcLegacySpeed:
|
||||
case SpeedMode_SdCardDefaultSpeed:
|
||||
/* Set as normal speed, 3.3V. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control, SD_REG_BITS_ENUM(HOST_CONTROL_HIGH_SPEED_ENABLE, NORMAL_SPEED));
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 3_3V_SIGNALING));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control, SD_REG_BITS_ENUM(HOST_CONTROL_HIGH_SPEED_ENABLE, NORMAL_SPEED));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 3_3V_SIGNALING));
|
||||
break;
|
||||
case SpeedMode_MmcHighSpeed:
|
||||
case SpeedMode_SdCardHighSpeed:
|
||||
/* Set as high speed, 3.3V. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control, SD_REG_BITS_ENUM(HOST_CONTROL_HIGH_SPEED_ENABLE, HIGH_SPEED));
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 3_3V_SIGNALING));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control, SD_REG_BITS_ENUM(HOST_CONTROL_HIGH_SPEED_ENABLE, HIGH_SPEED));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 3_3V_SIGNALING));
|
||||
break;
|
||||
case SpeedMode_MmcHs200:
|
||||
/* Set as HS200, 1.8V. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_UHS_MODE_SELECT, HS200));
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_UHS_MODE_SELECT, HS200));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING));
|
||||
break;
|
||||
case SpeedMode_MmcHs400:
|
||||
/* Set as HS400, 1.8V. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_UHS_MODE_SELECT, HS400));
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_UHS_MODE_SELECT, HS400));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING));
|
||||
break;
|
||||
case SpeedMode_SdCardSdr12:
|
||||
/* Set as SDR12, 1.8V. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_UHS_MODE_SELECT, SDR12));
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_UHS_MODE_SELECT, SDR12));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING));
|
||||
break;
|
||||
case SpeedMode_SdCardSdr50:
|
||||
case SpeedMode_SdCardSdr104:
|
||||
case SpeedMode_GcAsicFpgaSpeed:
|
||||
case SpeedMode_GcAsicSpeed:
|
||||
/* Set as SDR104, 1.8V. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_UHS_MODE_SELECT, SDR104));
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_UHS_MODE_SELECT, SDR104));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING));
|
||||
break;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
@@ -417,13 +417,13 @@ namespace ams::sdmmc::impl {
|
||||
/* Write the divider val to clock control. */
|
||||
const u16 n = x / 2;
|
||||
const u16 upper_n = n >> 8;
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_VALUE(CLOCK_CONTROL_SDCLK_FREQUENCY_SELECT, n),
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_VALUE(CLOCK_CONTROL_SDCLK_FREQUENCY_SELECT, n),
|
||||
SD_REG_BITS_VALUE(CLOCK_CONTROL_UPPER_BITS_OF_SDCLK_FREQUENCY_SELECT, upper_n));
|
||||
|
||||
/* Re-enable the clock, if we should. */
|
||||
if (clock_enabled) {
|
||||
/* Turn on the clock. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
}
|
||||
|
||||
/* If speed mode is Hs400, calibrate dll. */
|
||||
@@ -432,7 +432,7 @@ namespace ams::sdmmc::impl {
|
||||
}
|
||||
|
||||
/* Set the current speed mode. */
|
||||
this->current_speed_mode = speed_mode;
|
||||
m_current_speed_mode = speed_mode;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
@@ -452,16 +452,16 @@ namespace ams::sdmmc::impl {
|
||||
{
|
||||
this->ClearInterrupt();
|
||||
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.normal_signal_enable, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, ENABLED));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.normal_signal_enable, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, ENABLED));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set the buffer read ready enable, and read status to ensure it takes. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.normal_int_enable, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, ENABLED));
|
||||
reg::Write(this->sdmmc_registers->sd_host_standard_registers.normal_int_status, reg::Read(this->sdmmc_registers->sd_host_standard_registers.normal_int_status));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.normal_int_enable, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, ENABLED));
|
||||
reg::Write(m_sdmmc_registers->sd_host_standard_registers.normal_int_status, reg::Read(m_sdmmc_registers->sd_host_standard_registers.normal_int_status));
|
||||
|
||||
/* Issue command with clock disabled. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE));
|
||||
{
|
||||
SdHostStandardController::SetCommandForTuning(command_index);
|
||||
|
||||
@@ -469,17 +469,17 @@ namespace ams::sdmmc::impl {
|
||||
WaitMicroSeconds(1);
|
||||
SdHostStandardController::AbortTransaction();
|
||||
}
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
|
||||
/* When we're done waiting, ensure that we clean up appropriately. */
|
||||
ON_SCOPE_EXIT {
|
||||
/* Clear the buffer read ready signal, if we should. */
|
||||
#if defined(AMS_SDMMC_USE_OS_EVENTS)
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.normal_signal_enable, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, MASKED));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.normal_signal_enable, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, MASKED));
|
||||
#endif
|
||||
|
||||
/* Clear the buffer read ready enable. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.normal_int_enable, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, MASKED));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.normal_int_enable, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, MASKED));
|
||||
|
||||
/* Wait 8 clocks to ensure configuration takes. */
|
||||
SdHostStandardController::EnsureControl();
|
||||
@@ -492,7 +492,7 @@ namespace ams::sdmmc::impl {
|
||||
const auto result = SdHostStandardController::WaitInterrupt(TuningCommandTimeoutMilliSeconds);
|
||||
if (R_SUCCEEDED(result)) {
|
||||
/* If we succeeded, clear the interrupt. */
|
||||
reg::Write(this->sdmmc_registers->sd_host_standard_registers.normal_int_status, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, ENABLED));
|
||||
reg::Write(m_sdmmc_registers->sd_host_standard_registers.normal_int_status, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, ENABLED));
|
||||
this->ClearInterrupt();
|
||||
return ResultSuccess();
|
||||
} else if (sdmmc::ResultWaitInterruptSoftwareTimeout::Includes(result)) {
|
||||
@@ -508,9 +508,9 @@ namespace ams::sdmmc::impl {
|
||||
ManualTimer timer(TuningCommandTimeoutMilliSeconds);
|
||||
while (true) {
|
||||
/* Check if we received the interrupt. */
|
||||
if (reg::HasValue(this->sdmmc_registers->sd_host_standard_registers.normal_int_status, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, ENABLED))) {
|
||||
if (reg::HasValue(m_sdmmc_registers->sd_host_standard_registers.normal_int_status, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, ENABLED))) {
|
||||
/* If we did, acknowledge it. */
|
||||
reg::Write(this->sdmmc_registers->sd_host_standard_registers.normal_int_status, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, ENABLED));
|
||||
reg::Write(m_sdmmc_registers->sd_host_standard_registers.normal_int_status, SD_REG_BITS_ENUM(NORMAL_INTERRUPT_BUFFER_READ_READY, ENABLED));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
@@ -530,7 +530,7 @@ namespace ams::sdmmc::impl {
|
||||
this->GetAutoCalOffsets(std::addressof(pd), std::addressof(pu), bus_power);
|
||||
|
||||
/* Set the offsets. */
|
||||
reg::ReadWrite(this->sdmmc_registers->auto_cal_config, SD_REG_BITS_VALUE(AUTO_CAL_CONFIG_AUTO_CAL_PD_OFFSET, pd),
|
||||
reg::ReadWrite(m_sdmmc_registers->auto_cal_config, SD_REG_BITS_VALUE(AUTO_CAL_CONFIG_AUTO_CAL_PD_OFFSET, pd),
|
||||
SD_REG_BITS_VALUE(AUTO_CAL_CONFIG_AUTO_CAL_PU_OFFSET, pu));
|
||||
|
||||
/* Wait for 1ms to ensure that our configuration takes. */
|
||||
@@ -541,22 +541,22 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
void SdmmcController::CalibrateDriveStrength(BusPower bus_power) {
|
||||
/* Reset drive strength calibration status. */
|
||||
this->drive_strength_calibration_status = sdmmc::ResultDriveStrengthCalibrationNotCompleted();
|
||||
m_drive_strength_calibration_status = sdmmc::ResultDriveStrengthCalibrationNotCompleted();
|
||||
|
||||
/* Check if we need to temporarily disable the device clock. */
|
||||
const bool clock_enabled = reg::HasValue(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
const bool clock_enabled = reg::HasValue(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
|
||||
/* Ensure that the clock is disabled for the period we're using it. */
|
||||
if (clock_enabled) {
|
||||
/* Turn off the clock. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE));
|
||||
}
|
||||
|
||||
/* Calibrate with the clock disabled. */
|
||||
{
|
||||
/* Set SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD. */
|
||||
if (reg::HasValue(this->sdmmc_registers->sdmemcomppadctrl, SD_REG_BITS_VALUE(SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD, 0))) {
|
||||
reg::ReadWrite(this->sdmmc_registers->sdmemcomppadctrl, SD_REG_BITS_VALUE(SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD, 1));
|
||||
if (reg::HasValue(m_sdmmc_registers->sdmemcomppadctrl, SD_REG_BITS_VALUE(SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD, 0))) {
|
||||
reg::ReadWrite(m_sdmmc_registers->sdmemcomppadctrl, SD_REG_BITS_VALUE(SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD, 1));
|
||||
SdHostStandardController::EnsureControl();
|
||||
WaitMicroSeconds(1);
|
||||
}
|
||||
@@ -564,7 +564,7 @@ namespace ams::sdmmc::impl {
|
||||
/* Calibrate with SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD set. */
|
||||
{
|
||||
/* Begin autocal. */
|
||||
reg::ReadWrite(this->sdmmc_registers->auto_cal_config, SD_REG_BITS_ENUM(AUTO_CAL_CONFIG_AUTO_CAL_START, ENABLED),
|
||||
reg::ReadWrite(m_sdmmc_registers->auto_cal_config, SD_REG_BITS_ENUM(AUTO_CAL_CONFIG_AUTO_CAL_START, ENABLED),
|
||||
SD_REG_BITS_ENUM(AUTO_CAL_CONFIG_AUTO_CAL_ENABLE, ENABLED));
|
||||
SdHostStandardController::EnsureControl();
|
||||
WaitMicroSeconds(2);
|
||||
@@ -573,14 +573,14 @@ namespace ams::sdmmc::impl {
|
||||
ManualTimer timer(10);
|
||||
while (true) {
|
||||
/* Check if auto cal is inactive. */
|
||||
if (reg::HasValue(this->sdmmc_registers->auto_cal_status, SD_REG_BITS_ENUM(AUTO_CAL_STATUS_AUTO_CAL_ACTIVE, INACTIVE))) {
|
||||
if (reg::HasValue(m_sdmmc_registers->auto_cal_status, SD_REG_BITS_ENUM(AUTO_CAL_STATUS_AUTO_CAL_ACTIVE, INACTIVE))) {
|
||||
/* Check the pullup status. */
|
||||
const u32 pullup = (reg::GetValue(this->sdmmc_registers->auto_cal_status, SD_REG_BITS_MASK(AUTO_CAL_STATUS_AUTO_CAL_PULLUP))) & 0x1F;
|
||||
const u32 pullup = (reg::GetValue(m_sdmmc_registers->auto_cal_status, SD_REG_BITS_MASK(AUTO_CAL_STATUS_AUTO_CAL_PULLUP))) & 0x1F;
|
||||
if (pullup == 0x1F) {
|
||||
this->drive_strength_calibration_status = sdmmc::ResultSdmmcCompShortToGnd();
|
||||
m_drive_strength_calibration_status = sdmmc::ResultSdmmcCompShortToGnd();
|
||||
}
|
||||
if (pullup == 0) {
|
||||
this->drive_strength_calibration_status = sdmmc::ResultSdmmcCompOpen();
|
||||
m_drive_strength_calibration_status = sdmmc::ResultSdmmcCompOpen();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -588,40 +588,40 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
/* Otherwise, check if we've timed out. */
|
||||
if (!timer.Update()) {
|
||||
this->drive_strength_calibration_status = sdmmc::ResultDriveStrengthCalibrationSoftwareTimeout();
|
||||
m_drive_strength_calibration_status = sdmmc::ResultDriveStrengthCalibrationSoftwareTimeout();
|
||||
|
||||
this->SetDriveStrengthToDefaultValues(bus_power);
|
||||
reg::ReadWrite(this->sdmmc_registers->auto_cal_config, SD_REG_BITS_ENUM(AUTO_CAL_CONFIG_AUTO_CAL_ENABLE, DISABLED));
|
||||
reg::ReadWrite(m_sdmmc_registers->auto_cal_config, SD_REG_BITS_ENUM(AUTO_CAL_CONFIG_AUTO_CAL_ENABLE, DISABLED));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sdmemcomppadctrl, SD_REG_BITS_VALUE(SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD, 0));
|
||||
reg::ReadWrite(m_sdmmc_registers->sdmemcomppadctrl, SD_REG_BITS_VALUE(SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD, 0));
|
||||
}
|
||||
|
||||
/* Re-enable the clock, if we should. */
|
||||
if (clock_enabled) {
|
||||
/* Turn on the clock. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
}
|
||||
|
||||
/* If calibration didn't receive a replacement error, set internal state to success. */
|
||||
if (sdmmc::ResultDriveStrengthCalibrationNotCompleted::Includes(this->drive_strength_calibration_status)) {
|
||||
this->drive_strength_calibration_status = ResultSuccess();
|
||||
if (sdmmc::ResultDriveStrengthCalibrationNotCompleted::Includes(m_drive_strength_calibration_status)) {
|
||||
m_drive_strength_calibration_status = ResultSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
Result SdmmcController::Startup(BusPower bus_power, BusWidth bus_width, SpeedMode speed_mode, bool power_saving_enable) {
|
||||
/* Verify that we're awake. */
|
||||
AMS_ABORT_UNLESS(this->is_awake);
|
||||
AMS_ABORT_UNLESS(m_is_awake);
|
||||
|
||||
/* Release the controller from reset. */
|
||||
this->ReleaseReset(speed_mode);
|
||||
|
||||
/* Mark that we're not shutdown. */
|
||||
this->is_shutdown = false;
|
||||
m_is_shutdown = false;
|
||||
|
||||
/* Power on the controller. */
|
||||
R_TRY(this->PowerOn(bus_power));
|
||||
@@ -646,12 +646,12 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
void SdmmcController::Shutdown() {
|
||||
/* If we're already shut down, there's nothing to do. */
|
||||
if (this->is_shutdown) {
|
||||
if (m_is_shutdown) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're currently awake, we need to disable clock/power. */
|
||||
if (this->is_awake) {
|
||||
if (m_is_awake) {
|
||||
SdHostStandardController::DisableDeviceClock();
|
||||
SdHostStandardController::SetBusPower(BusPower_Off);
|
||||
SdHostStandardController::EnsureControl();
|
||||
@@ -661,26 +661,26 @@ namespace ams::sdmmc::impl {
|
||||
this->PowerOff();
|
||||
|
||||
/* If awake, assert reset. */
|
||||
if (this->is_awake) {
|
||||
if (m_is_awake) {
|
||||
this->AssertReset();
|
||||
}
|
||||
|
||||
/* Mark that we're shutdown. */
|
||||
this->is_shutdown = true;
|
||||
m_is_shutdown = true;
|
||||
}
|
||||
|
||||
void SdmmcController::PutToSleep() {
|
||||
/* If we're already shut down or asleep, there's nothing to do. */
|
||||
if (this->is_shutdown || !this->is_awake) {
|
||||
if (m_is_shutdown || !m_is_awake) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save values before sleep. */
|
||||
this->bus_power_before_sleep = SdHostStandardController::GetBusPower();
|
||||
this->bus_width_before_sleep = SdHostStandardController::GetBusWidth();
|
||||
this->speed_mode_before_sleep = this->current_speed_mode;
|
||||
this->tap_value_before_sleep = this->GetCurrentTapValue();
|
||||
this->is_powersaving_enable_before_sleep = SdHostStandardController::IsPowerSavingEnable();
|
||||
m_bus_power_before_sleep = SdHostStandardController::GetBusPower();
|
||||
m_bus_width_before_sleep = SdHostStandardController::GetBusWidth();
|
||||
m_speed_mode_before_sleep = m_current_speed_mode;
|
||||
m_tap_value_before_sleep = this->GetCurrentTapValue();
|
||||
m_is_powersaving_enable_before_sleep = SdHostStandardController::IsPowerSavingEnable();
|
||||
|
||||
/* Disable clock/power to the device. */
|
||||
SdHostStandardController::DisableDeviceClock();
|
||||
@@ -691,31 +691,31 @@ namespace ams::sdmmc::impl {
|
||||
this->AssertReset();
|
||||
|
||||
/* Mark that we're asleep. */
|
||||
this->is_awake = false;
|
||||
m_is_awake = false;
|
||||
}
|
||||
|
||||
Result SdmmcController::Awaken() {
|
||||
/* If we're shut down, or if we're awake already, there's nothing to do. */
|
||||
R_SUCCEED_IF(this->is_shutdown);
|
||||
R_SUCCEED_IF(this->is_awake);
|
||||
R_SUCCEED_IF(m_is_shutdown);
|
||||
R_SUCCEED_IF(m_is_awake);
|
||||
|
||||
/* Mark that we're awake. */
|
||||
this->is_awake = true;
|
||||
m_is_awake = true;
|
||||
|
||||
/* Clear pad parked status. */
|
||||
this->ClearPadParked();
|
||||
|
||||
/* Release reset. */
|
||||
this->ReleaseReset(this->speed_mode_before_sleep);
|
||||
this->ReleaseReset(m_speed_mode_before_sleep);
|
||||
|
||||
/* Start up for the correct power. */
|
||||
R_TRY(this->StartupCore(this->bus_power_before_sleep));
|
||||
R_TRY(this->StartupCore(m_bus_power_before_sleep));
|
||||
|
||||
/* Configure values to what they were before sleep. */
|
||||
SdHostStandardController::SetBusWidth(this->bus_width_before_sleep);
|
||||
SdHostStandardController::SetBusPower(this->bus_power_before_sleep);
|
||||
R_TRY(this->SetSpeedModeWithTapValue(this->speed_mode_before_sleep, this->tap_value_before_sleep));
|
||||
this->SetPowerSaving(this->is_powersaving_enable_before_sleep);
|
||||
SdHostStandardController::SetBusWidth(m_bus_width_before_sleep);
|
||||
SdHostStandardController::SetBusPower(m_bus_power_before_sleep);
|
||||
R_TRY(this->SetSpeedModeWithTapValue(m_speed_mode_before_sleep, m_tap_value_before_sleep));
|
||||
this->SetPowerSaving(m_is_powersaving_enable_before_sleep);
|
||||
|
||||
/* Enable clock to the device. */
|
||||
SdHostStandardController::EnableDeviceClock();
|
||||
@@ -726,10 +726,10 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
Result SdmmcController::SwitchToSdr12() {
|
||||
/* Disable clock. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, DISABLE));
|
||||
|
||||
/* Check that the dat lines are all low. */
|
||||
R_UNLESS(reg::HasValue(this->sdmmc_registers->sd_host_standard_registers.present_state, SD_REG_BITS_VALUE(PRESENT_STATE_DAT0_3_LINE_SIGNAL_LEVEL, 0b0000)), sdmmc::ResultSdCardNotReadyToVoltageSwitch());
|
||||
R_UNLESS(reg::HasValue(m_sdmmc_registers->sd_host_standard_registers.present_state, SD_REG_BITS_VALUE(PRESENT_STATE_DAT0_3_LINE_SIGNAL_LEVEL, 0b0000)), sdmmc::ResultSdCardNotReadyToVoltageSwitch());
|
||||
|
||||
/* Set Speed Mode. */
|
||||
R_TRY(this->SetSpeedMode(SpeedMode_SdCardSdr12));
|
||||
@@ -751,15 +751,15 @@ namespace ams::sdmmc::impl {
|
||||
WaitMicroSeconds(5000);
|
||||
|
||||
/* Check that we switched to 1.8V. */
|
||||
R_UNLESS(reg::HasValue(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING)), sdmmc::ResultSdHostStandardFailSwitchTo1_8V());
|
||||
R_UNLESS(reg::HasValue(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_1_8V_SIGNALING_ENABLE, 1_8V_SIGNALING)), sdmmc::ResultSdHostStandardFailSwitchTo1_8V());
|
||||
|
||||
/* Enable clock, and wait 1ms. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.clock_control, SD_REG_BITS_ENUM(CLOCK_CONTROL_SD_CLOCK_ENABLE, ENABLE));
|
||||
SdHostStandardController::EnsureControl();
|
||||
WaitMicroSeconds(1000);
|
||||
|
||||
/* Check that the dat lines are all high. */
|
||||
R_UNLESS(reg::HasValue(this->sdmmc_registers->sd_host_standard_registers.present_state, SD_REG_BITS_VALUE(PRESENT_STATE_DAT0_3_LINE_SIGNAL_LEVEL, 0b1111)), sdmmc::ResultSdCardNotCompleteVoltageSwitch());
|
||||
R_UNLESS(reg::HasValue(m_sdmmc_registers->sd_host_standard_registers.present_state, SD_REG_BITS_VALUE(PRESENT_STATE_DAT0_3_LINE_SIGNAL_LEVEL, 0b1111)), sdmmc::ResultSdCardNotCompleteVoltageSwitch());
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
@@ -768,8 +768,8 @@ namespace ams::sdmmc::impl {
|
||||
/* Get the tap value. */
|
||||
u8 tap_value;
|
||||
if (speed_mode == SpeedMode_MmcHs400) {
|
||||
AMS_ABORT_UNLESS(this->is_valid_tap_value_for_hs_400);
|
||||
tap_value = this->tap_value_for_hs_400;
|
||||
AMS_ABORT_UNLESS(m_is_valid_tap_value_for_hs_400);
|
||||
tap_value = m_tap_value_for_hs_400;
|
||||
} else {
|
||||
tap_value = this->GetDefaultInboundTapValue();
|
||||
}
|
||||
@@ -818,7 +818,7 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
Result SdmmcController::Tuning(SpeedMode speed_mode, u32 command_index) {
|
||||
/* Clear vendor tuning control 1. */
|
||||
reg::Write(this->sdmmc_registers->vendor_tuning_cntrl1, 0);
|
||||
reg::Write(m_sdmmc_registers->vendor_tuning_cntrl1, 0);
|
||||
|
||||
/* Determine/configure the number of tries. */
|
||||
int num_tries;
|
||||
@@ -827,25 +827,25 @@ namespace ams::sdmmc::impl {
|
||||
case SpeedMode_MmcHs400:
|
||||
case SpeedMode_SdCardSdr104:
|
||||
num_tries = 128;
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_tuning_cntrl0, SD_REG_BITS_ENUM(VENDOR_TUNING_CNTRL0_NUM_TUNING_ITERATIONS, TRIES_128));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_tuning_cntrl0, SD_REG_BITS_ENUM(VENDOR_TUNING_CNTRL0_NUM_TUNING_ITERATIONS, TRIES_128));
|
||||
break;
|
||||
case SpeedMode_SdCardSdr50:
|
||||
case SpeedMode_GcAsicFpgaSpeed:
|
||||
case SpeedMode_GcAsicSpeed:
|
||||
num_tries = 256;
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_tuning_cntrl0, SD_REG_BITS_ENUM(VENDOR_TUNING_CNTRL0_NUM_TUNING_ITERATIONS, TRIES_256));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_tuning_cntrl0, SD_REG_BITS_ENUM(VENDOR_TUNING_CNTRL0_NUM_TUNING_ITERATIONS, TRIES_256));
|
||||
break;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
|
||||
/* Configure the multiplier. */
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_tuning_cntrl0, SD_REG_BITS_VALUE(VENDOR_TUNING_CNTRL0_MUL_M, 1));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_tuning_cntrl0, SD_REG_BITS_VALUE(VENDOR_TUNING_CNTRL0_MUL_M, 1));
|
||||
|
||||
/* Configure tap value to be updated by hardware. */
|
||||
reg::ReadWrite(this->sdmmc_registers->vendor_tuning_cntrl0, SD_REG_BITS_ENUM(VENDOR_TUNING_CNTRL0_TAP_VALUE_UPDATED_BY_HW, UPDATED_BY_HW));
|
||||
reg::ReadWrite(m_sdmmc_registers->vendor_tuning_cntrl0, SD_REG_BITS_ENUM(VENDOR_TUNING_CNTRL0_TAP_VALUE_UPDATED_BY_HW, UPDATED_BY_HW));
|
||||
|
||||
/* Configure to execute tuning. */
|
||||
reg::ReadWrite(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_EXECUTE_TUNING, EXECUTE_TUNING));
|
||||
reg::ReadWrite(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_EXECUTE_TUNING, EXECUTE_TUNING));
|
||||
|
||||
/* Perform tuning num_tries times. */
|
||||
for (int i = 0; /* ... */; ++i) {
|
||||
@@ -860,70 +860,70 @@ namespace ams::sdmmc::impl {
|
||||
break;
|
||||
}
|
||||
|
||||
if (reg::HasValue(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_EXECUTE_TUNING, TUNING_COMPLETED))) {
|
||||
if (reg::HasValue(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_EXECUTE_TUNING, TUNING_COMPLETED))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we're using the tuned clock. */
|
||||
R_UNLESS(reg::HasValue(this->sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_SAMPLING_CLOCK, USING_TUNED_CLOCK)), sdmmc::ResultTuningFailed());
|
||||
R_UNLESS(reg::HasValue(m_sdmmc_registers->sd_host_standard_registers.host_control2, SD_REG_BITS_ENUM(HOST_CONTROL2_SAMPLING_CLOCK, USING_TUNED_CLOCK)), sdmmc::ResultTuningFailed());
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void SdmmcController::SaveTuningStatusForHs400() {
|
||||
/* Save the current tap value. */
|
||||
this->tap_value_for_hs_400 = GetCurrentTapValue();
|
||||
this->is_valid_tap_value_for_hs_400 = true;
|
||||
m_tap_value_for_hs_400 = GetCurrentTapValue();
|
||||
m_is_valid_tap_value_for_hs_400 = true;
|
||||
}
|
||||
|
||||
Result Sdmmc1Controller::PowerOnForRegisterControl(BusPower bus_power) {
|
||||
AMS_ABORT_UNLESS(bus_power == BusPower_3_3V);
|
||||
|
||||
/* Nintendo sets the current bus power regardless of whether the call succeeds. */
|
||||
ON_SCOPE_EXIT { this->current_bus_power = BusPower_3_3V; };
|
||||
ON_SCOPE_EXIT { m_current_bus_power = BusPower_3_3V; };
|
||||
|
||||
/* pcv::PowerOn(pcv::PowerControlTarget_SdCard, 3300000); */
|
||||
R_TRY(this->power_controller->PowerOn(BusPower_3_3V));
|
||||
R_TRY(m_power_controller->PowerOn(BusPower_3_3V));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void Sdmmc1Controller::PowerOffForRegisterControl() {
|
||||
/* If we're already off, there's nothing to do. */
|
||||
if (this->current_bus_power == BusPower_Off) {
|
||||
if (m_current_bus_power == BusPower_Off) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're at 3.3V, lower to 1.8V. */
|
||||
if (this->current_bus_power == BusPower_3_3V) {
|
||||
if (m_current_bus_power == BusPower_3_3V) {
|
||||
/* pcv::ChangeVoltage(pcv::PowerControlTarget_SdCard, 1800000); */
|
||||
this->power_controller->LowerBusPower();
|
||||
m_power_controller->LowerBusPower();
|
||||
|
||||
/* Set our bus power. */
|
||||
this->current_bus_power = BusPower_1_8V;
|
||||
m_current_bus_power = BusPower_1_8V;
|
||||
}
|
||||
|
||||
/* pinmux::SetPinAssignment(std::addressof(this->pinmux_session), pinmux::PinAssignment_Sdmmc1OutputHigh); */
|
||||
/* pinmux::SetPinAssignment(std::addressof(m_pinmux_session), pinmux::PinAssignment_Sdmmc1OutputHigh); */
|
||||
pinmux_impl::SetPinAssignment(pinmux_impl::PinAssignment_Sdmmc1OutputHigh);
|
||||
|
||||
|
||||
/* pcv::PowerOff(pcv::PowerControlTarget_SdCard); */
|
||||
this->power_controller->PowerOff();
|
||||
m_power_controller->PowerOff();
|
||||
|
||||
/* Set our bus power. */
|
||||
this->current_bus_power = BusPower_Off;
|
||||
m_current_bus_power = BusPower_Off;
|
||||
|
||||
/* pinmux::SetPinAssignment(std::addressof(this->pinmux_session), pinmux::PinAssignment_Sdmmc1ResetState); */
|
||||
/* pinmux::SetPinAssignment(std::addressof(m_pinmux_session), pinmux::PinAssignment_Sdmmc1ResetState); */
|
||||
pinmux_impl::SetPinAssignment(pinmux_impl::PinAssignment_Sdmmc1ResetState);
|
||||
}
|
||||
|
||||
Result Sdmmc1Controller::LowerBusPowerForRegisterControl() {
|
||||
/* Nintendo sets the current bus power regardless of whether the call succeeds. */
|
||||
ON_SCOPE_EXIT { this->current_bus_power = BusPower_1_8V; };
|
||||
ON_SCOPE_EXIT { m_current_bus_power = BusPower_1_8V; };
|
||||
|
||||
/* pcv::ChangeVoltage(pcv::PowerControlTarget_SdCard, 1800000); */
|
||||
R_TRY(this->power_controller->LowerBusPower());
|
||||
R_TRY(m_power_controller->LowerBusPower());
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
@@ -932,16 +932,16 @@ namespace ams::sdmmc::impl {
|
||||
SdHostStandardController::EnsureControl();
|
||||
|
||||
if (IsSocMariko()) {
|
||||
/* pinmux::SetPinAssignment(std::addressof(this->pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtEnable); */
|
||||
/* pinmux::SetPinAssignment(std::addressof(m_pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtEnable); */
|
||||
pinmux_impl::SetPinAssignment(pinmux_impl::PinAssignment_Sdmmc1SchmtEnable);
|
||||
} else {
|
||||
switch (bus_power) {
|
||||
case BusPower_1_8V:
|
||||
/* pinmux::SetPinAssignment(std::addressof(this->pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtEnable); */
|
||||
/* pinmux::SetPinAssignment(std::addressof(m_pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtEnable); */
|
||||
pinmux_impl::SetPinAssignment(pinmux_impl::PinAssignment_Sdmmc1SchmtEnable);
|
||||
break;
|
||||
case BusPower_3_3V:
|
||||
/* pinmux::SetPinAssignment(std::addressof(this->pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtDisable); */
|
||||
/* pinmux::SetPinAssignment(std::addressof(m_pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtDisable); */
|
||||
pinmux_impl::SetPinAssignment(pinmux_impl::PinAssignment_Sdmmc1SchmtDisable);
|
||||
break;
|
||||
case BusPower_Off:
|
||||
@@ -955,7 +955,7 @@ namespace ams::sdmmc::impl {
|
||||
AMS_ABORT_UNLESS(bus_power == BusPower_3_3V);
|
||||
|
||||
/* Nintendo sets the current bus power regardless of whether the call succeeds. */
|
||||
ON_SCOPE_EXIT { this->current_bus_power = BusPower_3_3V; };
|
||||
ON_SCOPE_EXIT { m_current_bus_power = BusPower_3_3V; };
|
||||
|
||||
/* TODO: return pcv::PowerOn(pcv::PowerControlTarget_SdCard, 3300000); */
|
||||
return ResultSuccess();
|
||||
@@ -963,28 +963,28 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
void Sdmmc1Controller::PowerOffForPcvControl() {
|
||||
/* If we're already off, there's nothing to do. */
|
||||
if (this->current_bus_power == BusPower_Off) {
|
||||
if (m_current_bus_power == BusPower_Off) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're at 3.3V, lower to 1.8V. */
|
||||
{
|
||||
/* TODO: pcv::ChangeVoltage(pcv::PowerControlTarget_SdCard, 1800000); */
|
||||
this->current_bus_power = BusPower_1_8V;
|
||||
m_current_bus_power = BusPower_1_8V;
|
||||
}
|
||||
|
||||
/* TODO: pinmux::SetPinAssignment(std::addressof(this->pinmux_session), pinmux::PinAssignment_Sdmmc1OutputHigh); */
|
||||
/* TODO: pinmux::SetPinAssignment(std::addressof(m_pinmux_session), pinmux::PinAssignment_Sdmmc1OutputHigh); */
|
||||
|
||||
/* TODO: pcv::PowerOff(pcv::PowerControlTarget_SdCard); */
|
||||
this->current_bus_power = BusPower_Off;
|
||||
m_current_bus_power = BusPower_Off;
|
||||
|
||||
/* TODO: pinmux::SetPinAssignment(std::addressof(this->pinmux_session), pinmux::PinAssignment_Sdmmc1ResetState); */
|
||||
/* TODO: pinmux::SetPinAssignment(std::addressof(m_pinmux_session), pinmux::PinAssignment_Sdmmc1ResetState); */
|
||||
|
||||
}
|
||||
|
||||
Result Sdmmc1Controller::LowerBusPowerForPcvControl() {
|
||||
/* Nintendo sets the current bus power regardless of whether the call succeeds. */
|
||||
ON_SCOPE_EXIT { this->current_bus_power = BusPower_1_8V; };
|
||||
ON_SCOPE_EXIT { m_current_bus_power = BusPower_1_8V; };
|
||||
|
||||
/* TODO: return pcv::ChangeVoltage(pcv::PowerControlTarget_SdCard, 1800000); */
|
||||
return ResultSuccess();
|
||||
@@ -994,14 +994,14 @@ namespace ams::sdmmc::impl {
|
||||
SdHostStandardController::EnsureControl();
|
||||
|
||||
if (IsSocMariko()) {
|
||||
/* TODO: pinmux::SetPinAssignment(std::addressof(this->pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtEnable); */
|
||||
/* TODO: pinmux::SetPinAssignment(std::addressof(m_pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtEnable); */
|
||||
} else {
|
||||
switch (bus_power) {
|
||||
case BusPower_1_8V:
|
||||
/* TODO: pinmux::SetPinAssignment(std::addressof(this->pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtEnable); */
|
||||
/* TODO: pinmux::SetPinAssignment(std::addressof(m_pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtEnable); */
|
||||
break;
|
||||
case BusPower_3_3V:
|
||||
/* TODO: pinmux::SetPinAssignment(std::addressof(this->pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtDisable); */
|
||||
/* TODO: pinmux::SetPinAssignment(std::addressof(m_pinmux_session), pinmux::PinAssignment_Sdmmc1SchmtDisable); */
|
||||
break;
|
||||
case BusPower_Off:
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
@@ -1012,7 +1012,7 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
Result Sdmmc1Controller::PowerOn(BusPower bus_power) {
|
||||
#if defined(AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL)
|
||||
if (this->is_pcv_control) {
|
||||
if (m_is_pcv_control) {
|
||||
return this->PowerOnForPcvControl(bus_power);
|
||||
} else
|
||||
#endif
|
||||
@@ -1023,7 +1023,7 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
void Sdmmc1Controller::PowerOff() {
|
||||
#if defined(AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL)
|
||||
if (this->is_pcv_control) {
|
||||
if (m_is_pcv_control) {
|
||||
return this->PowerOffForPcvControl();
|
||||
} else
|
||||
#endif
|
||||
@@ -1034,7 +1034,7 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
Result Sdmmc1Controller::LowerBusPower() {
|
||||
#if defined(AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL)
|
||||
if (this->is_pcv_control) {
|
||||
if (m_is_pcv_control) {
|
||||
return this->LowerBusPowerForPcvControl();
|
||||
} else
|
||||
#endif
|
||||
@@ -1045,7 +1045,7 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
void Sdmmc1Controller::SetSchmittTrigger(BusPower bus_power) {
|
||||
#if defined(AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL)
|
||||
if (this->is_pcv_control) {
|
||||
if (m_is_pcv_control) {
|
||||
return this->SetSchmittTriggerForPcvControl(bus_power);
|
||||
} else
|
||||
#endif
|
||||
@@ -1060,7 +1060,7 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
void Sdmmc1Controller::Finalize() {
|
||||
#if defined(AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL)
|
||||
if (this->is_pcv_control) {
|
||||
if (m_is_pcv_control) {
|
||||
return this->FinalizeForPcvControl();
|
||||
} else
|
||||
#endif
|
||||
@@ -1072,20 +1072,20 @@ namespace ams::sdmmc::impl {
|
||||
void Sdmmc1Controller::InitializeForRegisterControl() {
|
||||
#if defined(AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL)
|
||||
/* Mark ourselves as initialized by register control. */
|
||||
this->is_pcv_control = false;
|
||||
m_is_pcv_control = false;
|
||||
#endif
|
||||
|
||||
/* pinmux::Initialize(); */
|
||||
/* This just opens a session handle to pinmux service, no work to do. */
|
||||
|
||||
/* pinmux::OpenSession(std::addressof(this->pinmux_session), pinmux::AssignablePinGroupName_Sdmmc1); */
|
||||
/* pinmux::OpenSession(std::addressof(m_pinmux_session), pinmux::AssignablePinGroupName_Sdmmc1); */
|
||||
/* This just sets the session's internal value to the pin group name, so nothing to do here either. */
|
||||
|
||||
/* pcv::Initialize(); */
|
||||
/* This initializes a lot of globals in pcv, most of which we don't care about. */
|
||||
/* However, we do care about the Sdmmc1PowerController. */
|
||||
AMS_ABORT_UNLESS(this->power_controller == nullptr);
|
||||
this->power_controller = util::ConstructAt(this->power_controller_storage);
|
||||
AMS_ABORT_UNLESS(m_power_controller == nullptr);
|
||||
m_power_controller = util::ConstructAt(m_power_controller_storage);
|
||||
|
||||
/* Perform base initialization. */
|
||||
SdmmcController::Initialize();
|
||||
@@ -1098,11 +1098,11 @@ namespace ams::sdmmc::impl {
|
||||
/* pcv::Finalize(); */
|
||||
/* As with initialize, we mostly don't care about the globals this touches. */
|
||||
/* However, we do want to finalize the Sdmmc1PowerController. */
|
||||
AMS_ABORT_UNLESS(this->power_controller != nullptr);
|
||||
this->power_controller = nullptr;
|
||||
util::DestroyAt(this->power_controller_storage);
|
||||
AMS_ABORT_UNLESS(m_power_controller != nullptr);
|
||||
m_power_controller = nullptr;
|
||||
util::DestroyAt(m_power_controller_storage);
|
||||
|
||||
/* pinmux::CloseSession(std::addressof(this->pinmux_session)); */
|
||||
/* pinmux::CloseSession(std::addressof(m_pinmux_session)); */
|
||||
/* This does nothing. */
|
||||
|
||||
/* pinmux::Finalize(); */
|
||||
@@ -1110,17 +1110,17 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
#if defined(AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL)
|
||||
/* Mark ourselves as initialized by register control. */
|
||||
this->is_pcv_control = false;
|
||||
m_is_pcv_control = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(AMS_SDMMC_USE_PCV_CLOCK_RESET_CONTROL)
|
||||
void Sdmmc1Controller::InitializeForPcvControl() {
|
||||
/* Mark ourselves as initialized by pcv control. */
|
||||
this->is_pcv_control = true;
|
||||
m_is_pcv_control = true;
|
||||
|
||||
/* TODO: pinmux::Initialize(); */
|
||||
/* TODO: pinmux::OpenSession(std::addressof(this->pinmux_session), pinmux::AssignablePinGroupName_Sdmmc1); */
|
||||
/* TODO: pinmux::OpenSession(std::addressof(m_pinmux_session), pinmux::AssignablePinGroupName_Sdmmc1); */
|
||||
/* TODO: pcv::Initialize(); */
|
||||
|
||||
/* Perform base initialization. */
|
||||
@@ -1132,11 +1132,11 @@ namespace ams::sdmmc::impl {
|
||||
SdmmcController::Finalize();
|
||||
|
||||
/* TODO: pcv::Finalize(); */
|
||||
/* TODO: pinmux::CloseSession(std::addressof(this->pinmux_session)); */
|
||||
/* TODO: pinmux::CloseSession(std::addressof(m_pinmux_session)); */
|
||||
/* TODO: pinmux::Finalize(); */
|
||||
|
||||
/* Mark ourselves as initialized by register control. */
|
||||
this->is_pcv_control = false;
|
||||
m_is_pcv_control = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1206,24 +1206,24 @@ namespace ams::sdmmc::impl {
|
||||
dd::ReadIoRegister(ApbdevPmcNoIoPowerAddress);
|
||||
}
|
||||
|
||||
Sdmmc1Controller::PowerController::PowerController() : current_bus_power(BusPower_Off) {
|
||||
Sdmmc1Controller::PowerController::PowerController() : m_current_bus_power(BusPower_Off) {
|
||||
/* gpio::Initialize(); */
|
||||
/* ... */
|
||||
|
||||
/* Open gpio session. */
|
||||
/* gpio::OpenSession(std::addressof(this->gpio_pad_session), gpio::GpioPadName_PowSdEn); */
|
||||
/* gpio::OpenSession(std::addressof(m_gpio_pad_session), gpio::GpioPadName_PowSdEn); */
|
||||
gpio_impl::OpenSession(gpio_impl::GpioPadName_PowSdEn);
|
||||
|
||||
/* Configure the gpio as low/output. */
|
||||
/* gpio::SetValue(std::addressof(this->gpio_pad_session), gpio::GpioValue_Low); */
|
||||
/* gpio::SetValue(std::addressof(m_gpio_pad_session), gpio::GpioValue_Low); */
|
||||
gpio_impl::SetValue(gpio_impl::GpioPadName_PowSdEn, gpio_impl::GpioValue_Low);
|
||||
|
||||
/* gpio::SetDirection(std::addressof(this->gpio_pad_session), gpio::Direction_Output); */
|
||||
/* gpio::SetDirection(std::addressof(m_gpio_pad_session), gpio::Direction_Output); */
|
||||
gpio_impl::SetDirection(gpio_impl::GpioPadName_PowSdEn, gpio_impl::Direction_Output);
|
||||
}
|
||||
|
||||
Sdmmc1Controller::PowerController::~PowerController() {
|
||||
/* gpio::CloseSession(std::addressof(this->gpio_pad_session)); */
|
||||
/* gpio::CloseSession(std::addressof(m_gpio_pad_session)); */
|
||||
gpio_impl::CloseSession(gpio_impl::GpioPadName_PowSdEn);
|
||||
|
||||
/* gpio::Finalize(); */
|
||||
@@ -1232,8 +1232,8 @@ namespace ams::sdmmc::impl {
|
||||
|
||||
Result Sdmmc1Controller::PowerController::PowerOn(BusPower bus_power) {
|
||||
/* Bus power should be off, and if it's not we don't need to do anything. */
|
||||
AMS_ASSERT(this->current_bus_power == BusPower_Off);
|
||||
R_SUCCEED_IF(this->current_bus_power != BusPower_Off);
|
||||
AMS_ASSERT(m_current_bus_power == BusPower_Off);
|
||||
R_SUCCEED_IF(m_current_bus_power != BusPower_Off);
|
||||
|
||||
/* Power on requires the target bus power be 3.3V. */
|
||||
AMS_ABORT_UNLESS(bus_power == BusPower_3_3V);
|
||||
@@ -1242,7 +1242,7 @@ namespace ams::sdmmc::impl {
|
||||
this->ControlRailSdmmc1Io(true);
|
||||
|
||||
/* Set the SD power GPIO to high. */
|
||||
/* gpio::SetValue(std::addressof(this->gpio_pad_session), gpio::GpioValue_High); */
|
||||
/* gpio::SetValue(std::addressof(m_gpio_pad_session), gpio::GpioValue_High); */
|
||||
gpio_impl::SetValue(gpio_impl::GpioPadName_PowSdEn, gpio_impl::GpioValue_High);
|
||||
|
||||
/* Wait 10ms for power change to take. */
|
||||
@@ -1256,27 +1256,27 @@ namespace ams::sdmmc::impl {
|
||||
WaitMicroSeconds(130);
|
||||
|
||||
/* Update our current bus power. */
|
||||
this->current_bus_power = bus_power;
|
||||
m_current_bus_power = bus_power;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Sdmmc1Controller::PowerController::PowerOff() {
|
||||
/* Bus power should be on, and if it's not we don't need to do anything. */
|
||||
AMS_ASSERT(this->current_bus_power != BusPower_Off);
|
||||
R_SUCCEED_IF(this->current_bus_power == BusPower_Off);
|
||||
AMS_ASSERT(m_current_bus_power != BusPower_Off);
|
||||
R_SUCCEED_IF(m_current_bus_power == BusPower_Off);
|
||||
|
||||
/* Bus power should be 1.8V. */
|
||||
/* NOTE: the result returned here is 0x8C0 (regulator::ResultIllegalRequest()) on newer firmwares. */
|
||||
AMS_ASSERT(this->current_bus_power == BusPower_1_8V);
|
||||
R_UNLESS(this->current_bus_power == BusPower_1_8V, pcv::ResultIllegalRequest());
|
||||
AMS_ASSERT(m_current_bus_power == BusPower_1_8V);
|
||||
R_UNLESS(m_current_bus_power == BusPower_1_8V, pcv::ResultIllegalRequest());
|
||||
|
||||
/* Disable vddio, and wait 4 ms. */
|
||||
this->ControlVddioSdmmc1(BusPower_Off);
|
||||
WaitMicroSeconds(4000);
|
||||
|
||||
/* Set the SD power GPIO to low. */
|
||||
/* gpio::SetValue(std::addressof(this->gpio_pad_session), gpio::GpioValue_Low); */
|
||||
/* gpio::SetValue(std::addressof(m_gpio_pad_session), gpio::GpioValue_Low); */
|
||||
gpio_impl::SetValue(gpio_impl::GpioPadName_PowSdEn, gpio_impl::GpioValue_Low);
|
||||
|
||||
/* Wait 239ms for the gpio config to take. */
|
||||
@@ -1287,15 +1287,15 @@ namespace ams::sdmmc::impl {
|
||||
this->SetSdmmcIoMode(true);
|
||||
|
||||
/* Update our current bus power. */
|
||||
this->current_bus_power = BusPower_Off;
|
||||
m_current_bus_power = BusPower_Off;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Sdmmc1Controller::PowerController::LowerBusPower() {
|
||||
/* Bus power should be 3.3V, and if it's not we don't need to do anything. */
|
||||
AMS_ASSERT(this->current_bus_power == BusPower_3_3V);
|
||||
R_SUCCEED_IF(this->current_bus_power != BusPower_3_3V);
|
||||
AMS_ASSERT(m_current_bus_power == BusPower_3_3V);
|
||||
R_SUCCEED_IF(m_current_bus_power != BusPower_3_3V);
|
||||
|
||||
/* Configure as 1.8V, then wait 150us for it to take. */
|
||||
R_TRY(this->ControlVddioSdmmc1(BusPower_1_8V));
|
||||
@@ -1303,7 +1303,7 @@ namespace ams::sdmmc::impl {
|
||||
this->SetSdmmcIoMode(false);
|
||||
|
||||
/* Update our current bus power. */
|
||||
this->current_bus_power = BusPower_1_8V;
|
||||
m_current_bus_power = BusPower_1_8V;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user