mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
Kernel/aarch64: Retrieve Pi 5 EMMC2 clock frequency from the devicetree
This commit is contained in:
1 parent
b37efc6925
commit
e1fd729c8b
2 files changed
+48
-5
No files matched your search
@@ -14,13 +14,40 @@
|
||||
|
||||
namespace Kernel::RPi {
|
||||
|
||||
SDHostController::SDHostController(Memory::TypedMapping<SD::HostControlRegisterMap volatile> registers)
|
||||
: m_registers(move(registers))
|
||||
SDHostController::SDHostController(Model model, DeviceTree::Device const& device, Memory::TypedMapping<SD::HostControlRegisterMap volatile> registers)
|
||||
: m_model(model)
|
||||
, m_device(device)
|
||||
, m_registers(move(registers))
|
||||
{
|
||||
}
|
||||
|
||||
ErrorOr<u32> SDHostController::retrieve_sd_clock_frequency()
|
||||
{
|
||||
if (m_model == Model::BCM2712_SDHCI) {
|
||||
// On the Pi 5, the "Get clock rate" mailbox message doesn't appear to work if the firmware didn't initialize the SD host controller.
|
||||
// In its devicetree, the EMMC2 clock is represented by a "fixed-clock" node, so get the frequency from there.
|
||||
// FIXME: Add a proper abstraction for devicetree clock hierarchies.
|
||||
|
||||
auto maybe_clocks = m_device.node().get_property("clocks"sv);
|
||||
if (!maybe_clocks.has_value() || maybe_clocks->size() != sizeof(u32))
|
||||
return ENOTSUP;
|
||||
|
||||
auto clock_phandle = maybe_clocks->as<u32>();
|
||||
|
||||
auto const* clock = DeviceTree::get().phandle(clock_phandle);
|
||||
if (clock == nullptr)
|
||||
return EINVAL;
|
||||
|
||||
if (!clock->is_compatible_with("fixed-clock"sv))
|
||||
return ENOTSUP;
|
||||
|
||||
auto maybe_clock_frequency = clock->get_property("clock-frequency"sv);
|
||||
if (!maybe_clock_frequency.has_value() || maybe_clock_frequency->size() != sizeof(u32))
|
||||
return EINVAL;
|
||||
|
||||
return maybe_clock_frequency->as<u32>();
|
||||
}
|
||||
|
||||
return Timer::get_clock_rate(Timer::ClockID::EMMC);
|
||||
}
|
||||
|
||||
@@ -32,12 +59,20 @@ static constinit Array const compatibles_array = {
|
||||
DEVICETREE_DRIVER(BCM2835SDHCIController, compatibles_array);
|
||||
|
||||
// https://www.kernel.org/doc/Documentation/devicetree/bindings/mmc/brcm,iproc-sdhci.yaml
|
||||
ErrorOr<void> BCM2835SDHCIController::probe(DeviceTree::Device const& device, StringView) const
|
||||
ErrorOr<void> BCM2835SDHCIController::probe(DeviceTree::Device const& device, StringView compatible) const
|
||||
{
|
||||
SDHostController::Model model;
|
||||
if (compatible == "brcm,bcm2712-sdhci"sv)
|
||||
model = SDHostController::Model::BCM2712_SDHCI;
|
||||
else if (compatible == "brcm,bcm2835-sdhci"sv)
|
||||
model = SDHostController::Model::BCM2835_SDHCI;
|
||||
else
|
||||
VERIFY_NOT_REACHED();
|
||||
|
||||
auto physical_address = TRY(device.get_resource(0)).paddr;
|
||||
|
||||
auto registers = TRY(Memory::map_typed_writable<SD::HostControlRegisterMap volatile>(physical_address));
|
||||
auto sdhc = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SDHostController(move(registers))));
|
||||
auto sdhc = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SDHostController(model, device, move(registers))));
|
||||
TRY(sdhc->initialize());
|
||||
|
||||
TRY(StorageManagement::the().add_controller(*sdhc));
|
||||
|
||||
@@ -8,13 +8,19 @@
|
||||
|
||||
#include <Kernel/Devices/Storage/SD/Registers.h>
|
||||
#include <Kernel/Devices/Storage/SD/SDHostController.h>
|
||||
#include <Kernel/Firmware/DeviceTree/Device.h>
|
||||
#include <Kernel/Memory/TypedMapping.h>
|
||||
|
||||
namespace Kernel::RPi {
|
||||
|
||||
class SDHostController : public ::SDHostController {
|
||||
public:
|
||||
SDHostController(Memory::TypedMapping<SD::HostControlRegisterMap volatile>);
|
||||
enum class Model {
|
||||
BCM2712_SDHCI,
|
||||
BCM2835_SDHCI,
|
||||
};
|
||||
|
||||
SDHostController(Model, DeviceTree::Device const&, Memory::TypedMapping<SD::HostControlRegisterMap volatile>);
|
||||
virtual ~SDHostController() override = default;
|
||||
|
||||
protected:
|
||||
@@ -23,6 +29,8 @@ protected:
|
||||
virtual ErrorOr<u32> retrieve_sd_clock_frequency() override;
|
||||
|
||||
private:
|
||||
Model m_model { Model::BCM2835_SDHCI };
|
||||
DeviceTree::Device const& m_device;
|
||||
Memory::TypedMapping<SD::HostControlRegisterMap volatile> m_registers;
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user