mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-22 09:21:57 -05:00
Kernel/aarch64: Make RPi::SDHostController a DeviceTree::Driver
This commit is contained in:
parent
cae52e39c2
commit
aa4c286138
5 changed files with 59 additions and 27 deletions
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue