mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 16:27:35 +00:00
Kernel: Wait for transactions to complete before stopping SD clock
This commit is contained in:
parent
b90a20aee6
commit
6185a19618
2 changed files with 12 additions and 4 deletions
|
@ -136,7 +136,7 @@ ErrorOr<NonnullLockRefPtr<SDMemoryCard>> SDHostController::try_initialize_insert
|
||||||
|
|
||||||
// NOTE: The SDHC might already have been initialized (e.g. by the bootloader), let's reset it to a known configuration
|
// NOTE: The SDHC might already have been initialized (e.g. by the bootloader), let's reset it to a known configuration
|
||||||
if (is_sd_clock_enabled())
|
if (is_sd_clock_enabled())
|
||||||
sd_clock_stop();
|
TRY(sd_clock_stop());
|
||||||
TRY(sd_clock_supply(400000));
|
TRY(sd_clock_supply(400000));
|
||||||
|
|
||||||
// PLSS 4.2.3: "Card Initialization and Identification Process"
|
// PLSS 4.2.3: "Card Initialization and Identification Process"
|
||||||
|
@ -459,12 +459,20 @@ ErrorOr<void> SDHostController::sd_clock_supply(u32 frequency)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDHostController::sd_clock_stop()
|
ErrorOr<void> SDHostController::sd_clock_stop()
|
||||||
{
|
{
|
||||||
// SDHC 3.2.2: "SD Clock Stop Sequence"
|
// SDHC 3.2.2: "SD Clock Stop Sequence"
|
||||||
|
|
||||||
|
// The Host Driver shall not clear SD Clock Enable while an SD transaction is executing on the SD Bus --
|
||||||
|
// namely, while either Command Inhibit (DAT) or Command Inhibit (CMD) in the Present State register
|
||||||
|
// is set to 1
|
||||||
|
if (!retry_with_timeout([&] { return !m_registers->present_state.command_inhibit_dat && !m_registers->present_state.command_inhibit_cmd; })) {
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
|
||||||
// 1. Set SD Clock Enable in the Clock Control register to 0
|
// 1. Set SD Clock Enable in the Clock Control register to 0
|
||||||
m_registers->host_configuration_1 = m_registers->host_configuration_1 & ~sd_clock_enable;
|
m_registers->host_configuration_1 = m_registers->host_configuration_1 & ~sd_clock_enable;
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> SDHostController::sd_clock_frequency_change(u32 new_frequency)
|
ErrorOr<void> SDHostController::sd_clock_frequency_change(u32 new_frequency)
|
||||||
|
@ -472,7 +480,7 @@ ErrorOr<void> SDHostController::sd_clock_frequency_change(u32 new_frequency)
|
||||||
// SDHC 3.2.3: "SD Clock Frequency Change Sequence"
|
// SDHC 3.2.3: "SD Clock Frequency Change Sequence"
|
||||||
|
|
||||||
// 1. Execute the SD Clock Stop Sequence
|
// 1. Execute the SD Clock Stop Sequence
|
||||||
sd_clock_stop();
|
TRY(sd_clock_stop());
|
||||||
|
|
||||||
// 2. Execute the SD Clock Supply Sequence
|
// 2. Execute the SD Clock Supply Sequence
|
||||||
return sd_clock_supply(new_frequency);
|
return sd_clock_supply(new_frequency);
|
||||||
|
|
|
@ -61,7 +61,7 @@ private:
|
||||||
ErrorOr<u32> calculate_sd_clock_divisor(u32 sd_clock_frequency, u32 frequency);
|
ErrorOr<u32> calculate_sd_clock_divisor(u32 sd_clock_frequency, u32 frequency);
|
||||||
bool is_sd_clock_enabled();
|
bool is_sd_clock_enabled();
|
||||||
ErrorOr<void> sd_clock_supply(u32 frequency);
|
ErrorOr<void> sd_clock_supply(u32 frequency);
|
||||||
void sd_clock_stop();
|
ErrorOr<void> sd_clock_stop();
|
||||||
ErrorOr<void> sd_clock_frequency_change(u32 frequency);
|
ErrorOr<void> sd_clock_frequency_change(u32 frequency);
|
||||||
ErrorOr<u32> retrieve_sd_clock_frequency();
|
ErrorOr<u32> retrieve_sd_clock_frequency();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue