Kernel/aarch64: Make RPi::SDHostController a DeviceTree::Driver

This commit is contained in:
Sönke Holz 2024-12-19 17:40:49 +01:00 committed by Nico Weber
parent cae52e39c2
commit aa4c286138
5 changed files with 59 additions and 27 deletions

View file

@ -60,6 +60,18 @@ void raspberry_pi_platform_init(StringView compatible_string)
dmesgln("RPi: Firmware version: {}", firmware_version);
RPi::Framebuffer::initialize();
// The BCM's SDHC is alternate function 3 on pins 21-27.
gpio.set_pin_function(21, RPi::GPIO::PinFunction::Alternate3); // CD
gpio.set_pin_high_detect_enable(21, true);
gpio.set_pin_function(22, RPi::GPIO::PinFunction::Alternate3); // SD1_CLK
gpio.set_pin_function(23, RPi::GPIO::PinFunction::Alternate3); // SD1_CMD
gpio.set_pin_function(24, RPi::GPIO::PinFunction::Alternate3); // SD1_DAT0
gpio.set_pin_function(25, RPi::GPIO::PinFunction::Alternate3); // SD1_DAT1
gpio.set_pin_function(26, RPi::GPIO::PinFunction::Alternate3); // SD1_DAT2
gpio.set_pin_function(27, RPi::GPIO::PinFunction::Alternate3); // SD1_DAT3
}
}

View file

@ -5,35 +5,44 @@
*/
#include <AK/Singleton.h>
#include <Kernel/Arch/aarch64/RPi/GPIO.h>
#include <Kernel/Arch/aarch64/RPi/MMIO.h>
#include <Kernel/Arch/aarch64/RPi/SDHostController.h>
#include <Kernel/Devices/Storage/StorageManagement.h>
#include <Kernel/Firmware/DeviceTree/DeviceTree.h>
#include <Kernel/Firmware/DeviceTree/Driver.h>
#include <Kernel/Firmware/DeviceTree/Management.h>
namespace Kernel::RPi {
Singleton<SDHostController> s_sdhc;
SDHostController& SDHostController::the()
SDHostController::SDHostController(Memory::TypedMapping<SD::HostControlRegisterMap volatile> registers)
: m_registers(move(registers))
{
return *s_sdhc;
}
SDHostController::SDHostController()
: ::SDHostController()
static constinit Array const compatibles_array = {
"brcm,bcm2835-sdhci"sv,
};
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
{
auto& gpio = GPIO::the();
gpio.set_pin_function(21, GPIO::PinFunction::Alternate3); // CD
gpio.set_pin_high_detect_enable(21, true);
auto physical_address = TRY(device.get_resource(0)).paddr;
gpio.set_pin_function(22, GPIO::PinFunction::Alternate3); // SD1_CLK
gpio.set_pin_function(23, GPIO::PinFunction::Alternate3); // SD1_CMD
DeviceTree::DeviceRecipe<NonnullRefPtr<StorageController>> recipe {
name(),
device.node_name(),
[physical_address] -> ErrorOr<NonnullRefPtr<StorageController>> {
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))));
TRY(sdhc->initialize());
return sdhc;
}
};
gpio.set_pin_function(24, GPIO::PinFunction::Alternate3); // SD1_DAT0
gpio.set_pin_function(25, GPIO::PinFunction::Alternate3); // SD1_DAT1
gpio.set_pin_function(26, GPIO::PinFunction::Alternate3); // SD1_DAT2
gpio.set_pin_function(27, GPIO::PinFunction::Alternate3); // SD1_DAT3
StorageManagement::add_recipe(move(recipe));
m_registers = MMIO::the().peripheral<SD::HostControlRegisterMap>(0x30'0000).release_value_but_fixme_should_propagate_errors();
return {};
}
}

View file

@ -14,8 +14,7 @@ namespace Kernel::RPi {
class SDHostController : public ::SDHostController {
public:
static SDHostController& the();
SDHostController();
SDHostController(Memory::TypedMapping<SD::HostControlRegisterMap volatile>);
virtual ~SDHostController() override = default;
protected:

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/NeverDestroyed.h>
#include <AK/Platform.h>
#include <AK/Singleton.h>
#include <AK/StringView.h>
@ -44,6 +45,8 @@ static Atomic<u32> s_relative_ahci_controller_id;
static Atomic<u32> s_relative_nvme_controller_id;
static Atomic<u32> s_relative_sd_controller_id;
static NeverDestroyed<Vector<DeviceTree::DeviceRecipe<NonnullRefPtr<StorageController>>>> s_recipes;
static constexpr int root_mount_flags = 0;
static constexpr StringView partition_uuid_prefix = "PARTUUID:"sv;
@ -93,6 +96,11 @@ void StorageManagement::remove_device(StorageDevice& device)
m_storage_devices.remove(device);
}
void StorageManagement::add_recipe(DeviceTree::DeviceRecipe<NonnullRefPtr<StorageController>> recipe)
{
s_recipes->append(move(recipe));
}
UNMAP_AFTER_INIT void StorageManagement::enumerate_pci_controllers(bool nvme_poll)
{
VERIFY(m_controllers.is_empty());
@ -490,14 +498,15 @@ UNMAP_AFTER_INIT void StorageManagement::initialize(bool poll)
enumerate_pci_controllers(poll);
}
#if ARCH(AARCH64)
auto& rpi_sdhc = RPi::SDHostController::the();
if (auto maybe_error = rpi_sdhc.initialize(); maybe_error.is_error()) {
dmesgln("Unable to initialize RaspberryPi's SD Host Controller: {}", maybe_error.error());
} else {
m_controllers.append(rpi_sdhc);
for (auto& recipe : *s_recipes) {
auto device_or_error = recipe.create_device();
if (device_or_error.is_error()) {
dmesgln("StorageManagement: Failed to create storage controller for device \"{}\" with driver {}: {}", recipe.node_name, recipe.driver_name, device_or_error.release_error());
continue;
}
m_controllers.append(device_or_error.release_value());
}
#endif
enumerate_storage_devices();
enumerate_disk_partitions();

View file

@ -14,6 +14,7 @@
#include <Kernel/Devices/Storage/StorageDevice.h>
#include <Kernel/Devices/Storage/StorageDevicePartition.h>
#include <Kernel/FileSystem/FileSystem.h>
#include <Kernel/Firmware/DeviceTree/DeviceRecipe.h>
#include <Kernel/Library/NonnullLockRefPtr.h>
#include <LibPartition/PartitionTable.h>
@ -44,6 +45,8 @@ public:
void add_device(StorageDevice&);
void remove_device(StorageDevice&);
static void add_recipe(DeviceTree::DeviceRecipe<NonnullRefPtr<StorageController>>);
private:
void enumerate_pci_controllers(bool nvme_poll);
void enumerate_storage_devices();