mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-24 07:46:42 +00:00
imx8mq_platform_drv: introduce reset domains
A reset domain can consist of one or several reset-pins denoted by name that are assigned to a device. When the device gets acquired via the Platform RPC API, the pins are de-asserted, and asserted again when the device gets released. A configuration looks like the following: <device name="mipi_dsi> <reset-domain name="mipi_dsi_pclk"/> ... </device> Fixes #4171
This commit is contained in:
parent
ed7d6c74f4
commit
7f6f710bd2
@ -47,6 +47,11 @@ void Device_model::destroy_element(Device & dev)
|
||||
device._power_domain_list.destroy_all_elements(policy);
|
||||
}
|
||||
|
||||
{
|
||||
Reset_domain_update_policy policy(_env.heap);
|
||||
device._reset_domain_list.destroy_all_elements(policy);
|
||||
}
|
||||
|
||||
Genode::destroy(_env.heap, &device);
|
||||
}
|
||||
|
||||
@ -88,4 +93,9 @@ void Device_model::update_element(Device & dev,
|
||||
Power_domain_update_policy policy(_env.heap);
|
||||
device._power_domain_list.update_from_xml(policy, node);
|
||||
}
|
||||
|
||||
{
|
||||
Reset_domain_update_policy policy(_env.heap);
|
||||
device._reset_domain_list.update_from_xml(policy, node);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <ccm.h>
|
||||
#include <gpc.h>
|
||||
#include <src.h>
|
||||
#include <device.h>
|
||||
|
||||
namespace Driver {
|
||||
@ -37,6 +38,7 @@ struct Driver::Env
|
||||
Attached_rom_dataspace config { env, "config" };
|
||||
Ccm ccm { env };
|
||||
Gpc gpc { env };
|
||||
Src src { env };
|
||||
Device_model devices { *this };
|
||||
|
||||
Env(Genode::Env &env) : env(env) { }
|
||||
|
@ -23,6 +23,8 @@ bool Driver::Imx_device::acquire(Driver::Session_component & sc)
|
||||
if (ret) {
|
||||
_power_domain_list.for_each([&] (Power_domain & p) {
|
||||
sc.env().gpc.enable(p.name); });
|
||||
_reset_domain_list.for_each([&] (Reset_domain & r) {
|
||||
sc.env().src.enable(r.name); });
|
||||
_clock_list.for_each([&] (Clock & c) {
|
||||
Avl_string_base * asb =
|
||||
sc.env().ccm.tree.first()->find_by_name(c.name.string());
|
||||
@ -46,6 +48,8 @@ bool Driver::Imx_device::acquire(Driver::Session_component & sc)
|
||||
|
||||
void Driver::Imx_device::release(Session_component & sc)
|
||||
{
|
||||
_reset_domain_list.for_each([&] (Reset_domain & r) {
|
||||
sc.env().src.disable(r.name); });
|
||||
_power_domain_list.for_each([&] (Power_domain & p) {
|
||||
sc.env().gpc.disable(p.name); });
|
||||
_clock_list.for_each([&] (Clock & c) {
|
||||
|
@ -22,6 +22,7 @@ namespace Driver {
|
||||
class Imx_device;
|
||||
struct Clock_update_policy;
|
||||
struct Power_domain_update_policy;
|
||||
struct Reset_domain_update_policy;
|
||||
}
|
||||
|
||||
|
||||
@ -55,6 +56,15 @@ class Driver::Imx_device : public Driver::Device
|
||||
Power_domain(Name name) : name(name) {}
|
||||
};
|
||||
|
||||
struct Reset_domain : List_model<Reset_domain>::Element
|
||||
{
|
||||
using Name = Genode::String<64>;
|
||||
|
||||
Name name;
|
||||
|
||||
Reset_domain(Name name) : name(name) {}
|
||||
};
|
||||
|
||||
bool acquire(Session_component &) override;
|
||||
void release(Session_component &) override;
|
||||
|
||||
@ -71,6 +81,7 @@ class Driver::Imx_device : public Driver::Device
|
||||
|
||||
List_model<Clock> _clock_list {};
|
||||
List_model<Power_domain> _power_domain_list {};
|
||||
List_model<Reset_domain> _reset_domain_list {};
|
||||
};
|
||||
|
||||
|
||||
@ -138,4 +149,35 @@ struct Driver::Power_domain_update_policy
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Driver::Reset_domain_update_policy
|
||||
: Genode::List_model<Imx_device::Reset_domain>::Update_policy
|
||||
{
|
||||
Genode::Allocator & alloc;
|
||||
|
||||
Reset_domain_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
|
||||
|
||||
void destroy_element(Element & pd) {
|
||||
Genode::destroy(alloc, &pd); }
|
||||
|
||||
Element & create_element(Genode::Xml_node node)
|
||||
{
|
||||
Element::Name name = node.attribute_value("name", Element::Name());
|
||||
return *(new (alloc) Element(name));
|
||||
}
|
||||
|
||||
void update_element(Element &, Genode::Xml_node) {}
|
||||
|
||||
static bool element_matches_xml_node(Element const & pd, Genode::Xml_node node)
|
||||
{
|
||||
Element::Name name = node.attribute_value("name", Element::Name());
|
||||
return name == pd.name;
|
||||
}
|
||||
|
||||
static bool node_is_element(Genode::Xml_node node)
|
||||
{
|
||||
return node.has_type("reset-domain");
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _SRC__DRIVERS__PLATFORM__IMX8MQ__IMX_DEVICE_H_ */
|
||||
|
58
repos/os/src/drivers/platform/imx8mq/src.h
Normal file
58
repos/os/src/drivers/platform/imx8mq/src.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* \brief System reset controller for i.MX8
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2021-05-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <base/env.h>
|
||||
#include <base/log.h>
|
||||
#include <os/attached_mmio.h>
|
||||
#include <util/string.h>
|
||||
|
||||
struct Src : Genode::Attached_mmio
|
||||
{
|
||||
struct Mipi_phy : Register<0x28, 32>
|
||||
{
|
||||
struct Byte : Bitfield<1, 1> {};
|
||||
struct Reset : Bitfield<2, 1> {};
|
||||
struct Dpi : Bitfield<3, 1> {};
|
||||
struct Esc : Bitfield<4, 1> {};
|
||||
struct Pclk : Bitfield<5, 1> {};
|
||||
};
|
||||
|
||||
void enable(Genode::String<64> name)
|
||||
{
|
||||
if (name == "mipi_dsi_byte") { write<Mipi_phy::Byte>(1); return; }
|
||||
if (name == "mipi_dsi_dpi") { write<Mipi_phy::Dpi>(1); return; }
|
||||
if (name == "mipi_dsi_esc") { write<Mipi_phy::Esc>(1); return; }
|
||||
if (name == "mipi_dsi_pclk") { write<Mipi_phy::Pclk>(1); return; }
|
||||
warning("Reset domain ", name, " is unknown!");
|
||||
}
|
||||
|
||||
void disable(Genode::String<64> name)
|
||||
{
|
||||
if (name == "mipi_dsi_byte") { write<Mipi_phy::Byte>(0); return; }
|
||||
if (name == "mipi_dsi_dpi") { write<Mipi_phy::Dpi>(0); return; }
|
||||
if (name == "mipi_dsi_esc") { write<Mipi_phy::Esc>(0); return; }
|
||||
if (name == "mipi_dsi_pclk") { write<Mipi_phy::Pclk>(0); return; }
|
||||
warning("Reset domain ", name, " is unknown!");
|
||||
}
|
||||
|
||||
enum {
|
||||
SRC_MMIO_BASE = 0x30390000,
|
||||
SRC_MMIO_SIZE = 0x10000,
|
||||
};
|
||||
|
||||
Src(Genode::Env & env)
|
||||
: Attached_mmio(env, SRC_MMIO_BASE, SRC_MMIO_SIZE) { };
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user