diff --git a/repos/os/include/spec/arm/platform_session/connection.h b/repos/os/include/spec/arm/platform_session/connection.h index a13d3a207f..2f3c7dc868 100644 --- a/repos/os/include/spec/arm/platform_session/connection.h +++ b/repos/os/include/spec/arm/platform_session/connection.h @@ -50,6 +50,14 @@ class Platform::Connection : public Genode::Connection, Client(cap()), _rm(env.rm()) { _try_attach(); } + void update() + { + if (_ds.constructed() && _rom.update() == true) { return; } + _try_attach(); + } + + void sigh(Signal_context_capability sigh) { _rom.sigh(sigh); } + Device_capability acquire_device(String const &device) override { return retry_with_upgrade(Ram_quota{6*1024}, Cap_quota{6}, [&] () { diff --git a/repos/os/include/spec/arm/platform_session/platform_session.h b/repos/os/include/spec/arm/platform_session/platform_session.h index efcd40b7e3..4fea08059f 100644 --- a/repos/os/include/spec/arm/platform_session/platform_session.h +++ b/repos/os/include/spec/arm/platform_session/platform_session.h @@ -42,7 +42,7 @@ struct Platform::Session : Genode::Session */ static const char *service_name() { return "Platform"; } - enum { RAM_QUOTA = 16 * 1024, CAP_QUOTA = 6 }; + enum { RAM_QUOTA = 32 * 1024, CAP_QUOTA = 6 }; virtual ~Session() { } diff --git a/repos/os/include/spec/arm_64/platform_device/client.h b/repos/os/include/spec/arm_64/platform_device/client.h new file mode 100644 index 0000000000..1154f98df4 --- /dev/null +++ b/repos/os/include/spec/arm_64/platform_device/client.h @@ -0,0 +1 @@ +#include diff --git a/repos/os/include/spec/arm_64/platform_device/platform_device.h b/repos/os/include/spec/arm_64/platform_device/platform_device.h new file mode 100644 index 0000000000..05e0a4a768 --- /dev/null +++ b/repos/os/include/spec/arm_64/platform_device/platform_device.h @@ -0,0 +1 @@ +#include diff --git a/repos/os/include/spec/arm_64/platform_session/client.h b/repos/os/include/spec/arm_64/platform_session/client.h new file mode 100644 index 0000000000..aa1a686332 --- /dev/null +++ b/repos/os/include/spec/arm_64/platform_session/client.h @@ -0,0 +1 @@ +#include diff --git a/repos/os/include/spec/arm_64/platform_session/connection.h b/repos/os/include/spec/arm_64/platform_session/connection.h new file mode 100644 index 0000000000..e282794775 --- /dev/null +++ b/repos/os/include/spec/arm_64/platform_session/connection.h @@ -0,0 +1 @@ +#include diff --git a/repos/os/include/spec/arm_64/platform_session/platform_session.h b/repos/os/include/spec/arm_64/platform_session/platform_session.h new file mode 100644 index 0000000000..bccc1d2260 --- /dev/null +++ b/repos/os/include/spec/arm_64/platform_session/platform_session.h @@ -0,0 +1 @@ +#include diff --git a/repos/os/recipes/api/platform_session/content.mk b/repos/os/recipes/api/platform_session/content.mk index fab30e1a94..e5fecf9133 100644 --- a/repos/os/recipes/api/platform_session/content.mk +++ b/repos/os/recipes/api/platform_session/content.mk @@ -1,5 +1,7 @@ INCLUDE_SUB_DIRS := platform_session \ platform_device \ + spec/arm_64/platform_session \ + spec/arm_64/platform_device \ spec/arm/platform_session \ spec/arm/platform_device \ spec/imx53/platform_session \ diff --git a/repos/os/recipes/raw/drivers_interactive-pbxa9/drivers.config b/repos/os/recipes/raw/drivers_interactive-pbxa9/drivers.config index 1f1fc80ea2..c2da674548 100644 --- a/repos/os/recipes/raw/drivers_interactive-pbxa9/drivers.config +++ b/repos/os/recipes/raw/drivers_interactive-pbxa9/drivers.config @@ -22,24 +22,24 @@ - + - + - - + + - - + + diff --git a/repos/os/recipes/raw/drivers_nic-pbxa9/drivers.config b/repos/os/recipes/raw/drivers_nic-pbxa9/drivers.config index 73de42c61c..3cad1eb049 100644 --- a/repos/os/recipes/raw/drivers_nic-pbxa9/drivers.config +++ b/repos/os/recipes/raw/drivers_nic-pbxa9/drivers.config @@ -24,8 +24,8 @@ - - + + diff --git a/repos/os/src/drivers/platform/imx8mq/ccm.cc b/repos/os/src/drivers/platform/imx8mq/ccm.cc new file mode 100644 index 0000000000..dd40728ec7 --- /dev/null +++ b/repos/os/src/drivers/platform/imx8mq/ccm.cc @@ -0,0 +1,420 @@ +/* + * \brief Central clock module for i.MX8MQ + * \author Stefan Kalkowski + * \date 2020-06-12 + */ + +/* + * Copyright (C) 2020 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. + */ + +#include + +/****************************** + ** Frac_pll immplementation ** + ******************************/ + +void Driver::Ccm::Frac_pll::disable() +{ + write(1); +} + + +void Driver::Ccm::Frac_pll::enable() +{ + if (!read()) return; + + write(0); + + for (unsigned i = 0; i < 0xfffff; i++) { + if (read()) { break; } + } +} + + +Driver::Clock & Driver::Ccm::Frac_pll::_parent() const +{ + Name pname; + + switch (read()) { + case Config_reg_0::Ref_sel::REF_CLK_25M: pname = "25m_ref_clk"; break; + case Config_reg_0::Ref_sel::REF_CLK_27M: pname = "27m_ref_clk"; break; + case Config_reg_0::Ref_sel::HDMI_PHY_27M: pname = "hdmi_phy_27m_clk"; break; + case Config_reg_0::Ref_sel::CLK_P_N: pname = "no_clk"; break; + }; + + return static_cast(_tree.first()->find_by_name(pname.string()))->object(); +}; + + +void Driver::Ccm::Frac_pll::set_parent(Name parent) +{ + if (parent == "25m_ref_clk") { + write(Config_reg_0::Ref_sel::REF_CLK_25M); + return; + } + if (parent == "27m_ref_clk") { + write(Config_reg_0::Ref_sel::REF_CLK_27M); + return; + } + if (parent == "hdmi_phy_27m_clk") { + write(Config_reg_0::Ref_sel::HDMI_PHY_27M); + return; + } + write(Config_reg_0::Ref_sel::CLK_P_N); +} + + +void Driver::Ccm::Frac_pll::set_rate(unsigned long rate) +{ + static constexpr uint32_t fixed_frac = 1 << 24; + + uint64_t r = rate * 2; + uint64_t pr = _parent().get_rate() * 8; + uint32_t div_int = (uint32_t)((r / pr) & 0b1111111); + uint32_t div_frac = (uint32_t)((r - div_int * pr) * fixed_frac) / pr; + + Config_reg_1::access_t v = 0; + Config_reg_1::Int_div_ctl::set(v, div_int); + Config_reg_1::Frac_div_ctl::set(v, div_frac); + write(v); + + write(0); + write(0); + write(1); + + /* wait for ack, if powered and not bypassed */ + if (!(read() || + read())) { + for (unsigned i = 0; i < 0xfffff; i++) { + if (read()) { break; } + } + } + + write(0); +} + + +unsigned long Driver::Ccm::Frac_pll::get_rate() const +{ + static constexpr uint32_t fixed_frac = 1 << 24; + + uint32_t divq = (read() + 1) * 2; + uint32_t divr = read(); + uint32_t divff = read(); + uint32_t divfi = read(); + + uint64_t ref = _parent().get_rate() * 8 / divr; + + Genode::log("Frac_pll clock ", name(), " parent-rate ", _parent().get_rate()); + return (ref * (divfi + 1) / divq) + + (ref * divff / fixed_frac / divq); +} + + +Driver::Ccm::Frac_pll::Frac_pll(Name name, addr_t const base, Clock_tree & tree) +: Clock(name, tree), Mmio(base), _tree(tree) +{ + write(0); + write(1); +} + + +/****************************** + ** Sccg_pll immplementation ** + ******************************/ + +Driver::Clock & Driver::Ccm::Sccg_pll::_parent() const +{ + Name pname; + + switch (read()) { + case Config_reg_0::Ref_sel::REF_CLK_25M: pname = "25m_ref_clk"; break; + case Config_reg_0::Ref_sel::REF_CLK_27M: pname = "27m_ref_clk"; break; + case Config_reg_0::Ref_sel::HDMI_PHY_27M: pname = "hdmi_phy_27m_clk"; break; + case Config_reg_0::Ref_sel::CLK_P_N: pname = "no_clk"; break; + }; + + return static_cast(_tree.first()->find_by_name(pname.string()))->object(); +}; + + +void Driver::Ccm::Sccg_pll::set_parent(Name parent) +{ + if (parent == "25m_ref_clk") { + write(Config_reg_0::Ref_sel::REF_CLK_25M); + return; + } + if (parent == "27m_ref_clk") { + write(Config_reg_0::Ref_sel::REF_CLK_27M); + return; + } + if (parent == "hdmi_phy_27m_clk") { + write(Config_reg_0::Ref_sel::HDMI_PHY_27M); + return; + } + write(Config_reg_0::Ref_sel::CLK_P_N); +} + + +void Driver::Ccm::Sccg_pll::set_rate(unsigned long) +{ + Genode::error(__func__," not implemented yet!"); +} + + +unsigned long Driver::Ccm::Sccg_pll::get_rate() const +{ + unsigned factor = read() ? 8 : 2; + unsigned divf1 = read() + 1; + unsigned divf2 = read() + 1; + unsigned divr1 = read() + 1; + unsigned divr2 = read() + 1; + unsigned divq = read() + 1; + + unsigned long parent_rate = _parent().get_rate(); + + if (read()) { + return parent_rate; + } + + if (read()) { + return (parent_rate * divf2) / (divr2 * divq); + } + + return parent_rate * factor * divf1 * divf2 / (divr1*divr2*divq); +} + + +void Driver::Ccm::Sccg_pll::enable() +{ + if (!read()) return; + + write(0); + + for (unsigned i = 0; i < 0xfffff; i++) { + if (read()) { break; } + } +} + + +void Driver::Ccm::Sccg_pll::disable() +{ + write(1); +} + + +/******************************** + ** Root_clock immplementation ** + ********************************/ + +void Driver::Ccm::Root_clock::set_rate(unsigned long rate) +{ + uint32_t pre_div = 0; + uint32_t post_div = 0; + int deviation = (int)(~0U >> 1); + + unsigned long parent_rate = + _ref_clks[read()].ref.get_rate(); + + for (unsigned pre = 0; pre < (1<<3); pre++) { + for (unsigned post = 0; post < (1<<6); post++) { + int diff = (parent_rate / (pre+1)) / (post+1) - rate; + if (abs(diff) < abs(deviation)) { + pre_div = pre; + post_div = post; + deviation = diff; + } + } + } + + write(pre_div); + write(post_div); +}; + + +void Driver::Ccm::Root_clock::set_parent(Name name) +{ + for (unsigned i = 0; i < REF_CLK_MAX; i++) { + if (_ref_clks[i].ref.name() == name) { + write(i); + return; + } + } + + warning("Reference clock ", name, " cannot be set"); +} + + +unsigned long Driver::Ccm::Root_clock::get_rate() const +{ + unsigned long parent_rate = + _ref_clks[read()].ref.get_rate(); + unsigned pre = read()+1; + unsigned post = read()+1; + return parent_rate / pre / post; +} + + +void Driver::Ccm::Root_clock::enable() { write(1); } + + +void Driver::Ccm::Root_clock::disable() { write(0); } + + +/************************** + ** Gate immplementation ** + **************************/ + +void Driver::Ccm::Root_clock_divider::set_rate(unsigned long) +{ + warning(__func__, " not implemented yet!"); +} + + +unsigned long Driver::Ccm::Root_clock_divider::get_rate() const +{ + return _parent.get_rate() / read(); +}; + + +/************************** + ** Gate immplementation ** + **************************/ + +void Driver::Ccm::Gate::enable() { write(0x3); } + + +void Driver::Ccm::Gate::disable() { write(0x0); } + + +/******************* + ** CCM interface ** + *******************/ + +Driver::Ccm::Ccm(Genode::Env & env) : env(env) +{ + video_pll1_clk.enable(); + + /* set VIDEO PLL */ + video_pll1_clk.set_parent(m27_ref_clk.name()); + video_pll1_clk.set_rate(593999999); + + audio_pll1_clk.disable(); + audio_pll2_clk.disable(); + video_pll1_clk.disable(); + gpu_pll_clk.disable(); + vpu_pll_clk.disable(); + system_pll3_clk.disable(); + video_pll2_clk.disable(); + + usb_ctrl1_gate.disable(); + usb_ctrl2_gate.disable(); + usb_phy1_gate.disable(); + usb_phy2_gate.disable(); + + /* turn off all unnecessary root clocks */ + arm_m4_clk_root.disable(); + vpu_a53_clk_root.disable(); + gpu_core_clk_root.disable(); + gpu_shader_clk_root.disable(); + enet_axi_clk_root.disable(); + nand_usdhc_bus_clk_root.disable(); + vpu_bus_clk_root.disable(); + display_axi_clk_root.disable(); + display_apb_clk_root.disable(); + display_rtrm_clk_root.disable(); + usb_bus_clk_root.disable(); + gpu_axi_clk_root.disable(); + gpu_ahb_clk_root.disable(); + audio_ahb_clk_root.disable(); + mipi_dsi_esc_rx_clk_root.disable(); + vpu_g1_clk_root.disable(); + vpu_g2_clk_root.disable(); + display_dtrc_clk_root.disable(); + display_dc8000_clk_root.disable(); + pcie1_ctrl_clk_root.disable(); + pcie1_phy_clk_root.disable(); + pcie1_aux_clk_root.disable(); + dc_pixel_clk_root.disable(); + lcdif_pixel_clk_root.disable(); + sai1_clk_root.disable(); + sai2_clk_root.disable(); + sai3_clk_root.disable(); + sai4_clk_root.disable(); + sai5_clk_root.disable(); + sai6_clk_root.disable(); + spdif1_clk_root.disable(); + spdif2_clk_root.disable(); + enet_ref_clk_root.disable(); + enet_timer_clk_root.disable(); + enet_phy_ref_clk_root.disable(); + nand_clk_root.disable(); + qspi_clk_root.disable(); + usdhc1_clk_root.disable(); + usdhc2_clk_root.disable(); + i2c1_clk_root.disable(); + i2c2_clk_root.disable(); + i2c3_clk_root.disable(); + i2c4_clk_root.disable(); + uart2_clk_root.disable(); + uart3_clk_root.disable(); + uart4_clk_root.disable(); + usb_core_ref_clk_root.disable(); + usb_phy_ref_clk_root.disable(); + ecspi1_clk_root.disable(); + ecspi2_clk_root.disable(); + pwm1_clk_root.disable(); + pwm2_clk_root.disable(); + pwm3_clk_root.disable(); + pwm4_clk_root.disable(); + gpt1_clk_root.disable(); + gpt2_clk_root.disable(); + gpt3_clk_root.disable(); + gpt4_clk_root.disable(); + gpt5_clk_root.disable(); + gpt6_clk_root.disable(); + trace_clk_root.disable(); + wdog_clk_root.disable(); + wrclk_clk_root.disable(); + ipp_do_clko1clk_root.disable(); + ipp_do_clko2_clk_root.disable(); + mipi_dsi_core_clk_root.disable(); + mipi_dsi_phy_ref_clk_root.disable(); + mipi_dsi_dbi_clk_root.disable(); + old_mipi_dsi_esc_clk_root.disable(); + mipi_csi1_core_clk_root.disable(); + mipi_csi1_phy_ref_clk_root.disable(); + mipi_csi1_esc_clk_root.disable(); + mipi_csi2_core_clk_root.disable(); + mipi_csi2_phy_ref_clk_root.disable(); + mipi_csi2_esc_clk_root.disable(); + pcie2_ctrl_clk_root.disable(); + pcie2_phy_clk_root.disable(); + pcie2_aux_clk_root.disable(); + ecspi3_clk_root.disable(); + old_mipi_dsi_esc_rx_clk_root.disable(); + display_hdmi_clk_root.disable(); + + /* set certain reference clocks */ + ahb_clk_root.set_parent("system_pll1_div6"); + nand_usdhc_bus_clk_root.set_parent("system_pll1_div3"); + audio_ahb_clk_root.set_parent("system_pll2_div2"); + pcie1_ctrl_clk_root.set_parent("system_pll2_div5"); + pcie1_phy_clk_root.set_parent("system_pll2_div10"); + pcie2_ctrl_clk_root.set_parent("system_pll2_div5"); + pcie2_phy_clk_root.set_parent("system_pll2_div10"); + mipi_csi1_core_clk_root.set_parent("system_pll1_div3"); + mipi_csi1_phy_ref_clk_root.set_parent("system_pll2_clk"); + mipi_csi1_esc_clk_root.set_parent("system_pll1_clk"); + mipi_csi2_core_clk_root.set_parent("system_pll1_div3"); + mipi_csi2_phy_ref_clk_root.set_parent("system_pll2_clk"); + mipi_csi2_esc_clk_root.set_parent("system_pll1_clk"); + + /* increase NOC clock for better DDR performance */ + noc_clk_root.set_parent("system_pll1_clk"); + noc_clk_root.set_rate(800000000); +} diff --git a/repos/os/src/drivers/platform/imx8mq/ccm.h b/repos/os/src/drivers/platform/imx8mq/ccm.h new file mode 100644 index 0000000000..5866b47966 --- /dev/null +++ b/repos/os/src/drivers/platform/imx8mq/ccm.h @@ -0,0 +1,424 @@ +/* + * \brief Central clock module for i.MX8MQ + * \author Stefan Kalkowski + * \date 2020-06-12 + */ + +/* + * Copyright (C) 2020 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 +#include + +namespace Driver { + using namespace Genode; + + struct Ccm; +}; + +struct Driver::Ccm +{ + class Frac_pll : public Driver::Clock, Mmio + { + struct Config_reg_0 : Register<0x0, 32> + { + struct Output_div_value : Bitfield<0, 5> {}; + struct Refclk_div_value : Bitfield<5, 6> {}; + struct Newdiv_ack : Bitfield<11,1> {}; + struct Newdiv_val : Bitfield<12,1> {}; + struct Bypass : Bitfield<14,1> {}; + + struct Ref_sel : Bitfield<16,2> + { + enum Ref_clk { + REF_CLK_25M, REF_CLK_27M, HDMI_PHY_27M, CLK_P_N }; + }; + + struct Power_down : Bitfield<19,1> {}; + struct Out_enable : Bitfield<21,1> {}; + struct Lock_status : Bitfield<31,1> {}; + }; + + struct Config_reg_1 : Register<0x4, 32> + { + struct Int_div_ctl : Bitfield<0, 7> {}; + struct Frac_div_ctl : Bitfield<7, 24> {}; + }; + + Clock_tree & _tree; + + Clock & _parent() const; + + public: + + Frac_pll(Name name, + addr_t const base, + Clock_tree & tree); + + void set_parent(Name name) override; + void set_rate(unsigned long) override; + unsigned long get_rate() const override; + void enable() override; + void disable() override; + }; + + + class Sccg_pll : public Driver::Clock, Mmio + { + struct Config_reg_0 : Register<0x0, 32> + { + struct Ref_sel : Bitfield<0,2> { + enum Ref_clk { + REF_CLK_25M, REF_CLK_27M, HDMI_PHY_27M, CLK_P_N }; + }; + struct Bypass2 : Bitfield<4, 1> {}; + struct Bypass1 : Bitfield<5, 1> {}; + struct Power_down : Bitfield<7, 1> {}; + struct Out_enable : Bitfield<25,1> {}; + struct Lock_status : Bitfield<31,1> {}; + }; + + struct Config_reg_1 : Register<0x4, 32> + { + struct Sse : Bitfield<0,1> {}; + }; + + struct Config_reg_2 : Register<0x8, 32> + { + struct Output_div_val : Bitfield<1, 6> {}; + struct Feedback_divf2 : Bitfield<7, 6> {}; + struct Feedback_divf1 : Bitfield<13,6> {}; + struct Ref_divr2 : Bitfield<19,6> {}; + struct Ref_divr1 : Bitfield<25,3> {}; + }; + + Clock_tree & _tree; + + Clock & _parent() const; + + public: + + Sccg_pll(Name name, + addr_t const base, + Clock_tree & tree) + : Clock(name, tree), Mmio(base), _tree(tree) {} + + void set_parent(Name name) override; + void set_rate(unsigned long) override; + unsigned long get_rate() const override; + void enable() override; + void disable() override; + }; + + + class Root_clock : public Clock, Mmio + { + struct Target_reg : Register<0x0, 32> + { + struct Post_div : Bitfield<0,6> {}; + struct Pre_div : Bitfield<16,3> {}; + struct Ref_sel : Bitfield<24,3> {}; + struct Enable : Bitfield<28,1> {}; + }; + + struct Clock_ref { + Clock & ref; + Clock_ref(Clock & c) : ref(c) {} + }; + + enum { REF_CLK_MAX = 8 }; + + Clock_tree & _tree; + Clock_ref _ref_clks[REF_CLK_MAX]; + + Clock & _parent() const; + + public: + + Root_clock(Name name, + addr_t const base, + Clock & ref_clk0, + Clock & ref_clk1, + Clock & ref_clk2, + Clock & ref_clk3, + Clock & ref_clk4, + Clock & ref_clk5, + Clock & ref_clk6, + Clock & ref_clk7, + Clock_tree & tree) + : Clock(name, tree), Mmio(base), _tree(tree), + _ref_clks { ref_clk0, ref_clk1, ref_clk2, ref_clk3, + ref_clk4, ref_clk5, ref_clk6, ref_clk7 }{} + + void set_parent(Name name) override; + void set_rate(unsigned long) override; + unsigned long get_rate() const override; + void enable() override; + void disable() override; + }; + + + class Root_clock_divider : public Clock, Mmio + { + struct Target_reg : Register<0x0, 32> + { + struct Post_div : Bitfield<0,6> {}; + }; + + + Clock & _parent; + Clock_tree & _tree; + + public: + + Root_clock_divider(Name name, + addr_t const base, + Clock & parent, + Clock_tree & tree) + : Clock(name, tree), Mmio(base), + _parent(parent), _tree(tree) {} + + void set_rate(unsigned long) override; + unsigned long get_rate() const override; + }; + + + class Gate : public Clock, Mmio + { + struct Ccgr : Register<0x0, 32> { }; + + Clock & _parent; + + public: + + Gate(Name name, + addr_t const base, + Clock & parent, + Clock_tree & tree) + : Clock(name, tree), Mmio(base), _parent(parent) {} + + void set_rate(unsigned long) override {} + unsigned long get_rate() const override { + return _parent.get_rate(); } + + void enable() override; + void disable() override; + }; + + + enum { + CCM_MMIO_BASE = 0x30380000, + CCM_MMIO_SIZE = 0x10000, + CCM_ANALOG_MMIO_BASE = 0x30360000, + CCM_ANALOG_MMIO_SIZE = 0x10000, + }; + + Ccm(Genode::Env & env); + + Genode::Env & env; + Attached_mmio ccm_regs { env, CCM_MMIO_BASE, CCM_MMIO_SIZE }; + Attached_mmio ccm_analog_regs { env, CCM_ANALOG_MMIO_BASE, CCM_ANALOG_MMIO_SIZE }; + Clock::Clock_tree tree { }; + + addr_t frac_pll_base(unsigned pll) { + return (addr_t)ccm_analog_regs.local_addr() + pll*0x8; } + + addr_t sccg_pll_base(unsigned pll) { + return (addr_t)ccm_analog_regs.local_addr() + 0x30 + pll*0xc; } + + addr_t gate_base(unsigned nr) { + return (addr_t)ccm_regs.local_addr() + 0x4000 + nr*0x10; } + + addr_t root_base(unsigned nr) { + return (addr_t)ccm_regs.local_addr() + 0x8000 + nr*0x80; } + + Fixed_clock no_clk { "no_clk", 0, tree }; + Fixed_clock k32_ref_clk { "32k_ref_clk", 32 * 1000, tree }; + Fixed_clock m25_ref_clk { "25m_ref_clk", 25 * 1000 * 1000, tree }; + Fixed_clock m27_ref_clk { "27m_ref_clk", 27 * 1000 * 1000, tree }; + Fixed_clock hdmi_phy_m27_clk { "hdmi_phy_27m_clk", 27 * 1000 * 1000, tree }; + Fixed_clock ext_clk_1 { "ext_clk_1", 133 * 1000 * 1000, tree }; + Fixed_clock ext_clk_2 { "ext_clk_2", 133 * 1000 * 1000, tree }; + Fixed_clock ext_clk_3 { "ext_clk_3", 133 * 1000 * 1000, tree }; + Fixed_clock ext_clk_4 { "ext_clk_4", 133 * 1000 * 1000, tree }; + + Frac_pll audio_pll1_clk { "audio_pll1_clk", frac_pll_base(0), tree }; + Frac_pll audio_pll2_clk { "audio_pll2_clk", frac_pll_base(1), tree }; + Frac_pll video_pll1_clk { "video_pll1_clk", frac_pll_base(2), tree }; + Frac_pll gpu_pll_clk { "gpu_pll_clk", frac_pll_base(3), tree }; + Frac_pll vpu_pll_clk { "vpu_pll_clk", frac_pll_base(4), tree }; + Frac_pll arm_pll_clk { "arm_pll_clk", frac_pll_base(5), tree }; + + Sccg_pll system_pll1_clk { "system_pll1_clk", sccg_pll_base(0), tree }; + Sccg_pll system_pll2_clk { "system_pll2_clk", sccg_pll_base(1), tree }; + Sccg_pll system_pll3_clk { "system_pll3_clk", sccg_pll_base(2), tree }; + Sccg_pll video_pll2_clk { "video2_pll2_clk", sccg_pll_base(3), tree }; + Sccg_pll dram_pll_clk { "dram_pll_clk", sccg_pll_base(4), tree }; + + Fixed_divider system_pll1_div20 { "system_pll1_div20", system_pll1_clk, 20, tree }; + Fixed_divider system_pll1_div10 { "system_pll1_div10", system_pll1_clk, 10, tree }; + Fixed_divider system_pll1_div8 { "system_pll1_div8", system_pll1_clk, 8, tree }; + Fixed_divider system_pll1_div6 { "system_pll1_div6", system_pll1_clk, 6, tree }; + Fixed_divider system_pll1_div5 { "system_pll1_div5", system_pll1_clk, 5, tree }; + Fixed_divider system_pll1_div4 { "system_pll1_div4", system_pll1_clk, 4, tree }; + Fixed_divider system_pll1_div3 { "system_pll1_div3", system_pll1_clk, 3, tree }; + Fixed_divider system_pll1_div2 { "system_pll1_div2", system_pll1_clk, 2, tree }; + Fixed_divider system_pll2_div20 { "system_pll2_div20", system_pll2_clk, 20, tree }; + Fixed_divider system_pll2_div10 { "system_pll2_div10", system_pll2_clk, 10, tree }; + Fixed_divider system_pll2_div8 { "system_pll2_div8", system_pll2_clk, 8, tree }; + Fixed_divider system_pll2_div6 { "system_pll2_div6", system_pll2_clk, 6, tree }; + Fixed_divider system_pll2_div5 { "system_pll2_div5", system_pll2_clk, 5, tree }; + Fixed_divider system_pll2_div4 { "system_pll2_div4", system_pll2_clk, 4, tree }; + Fixed_divider system_pll2_div3 { "system_pll2_div3", system_pll2_clk, 3, tree }; + Fixed_divider system_pll2_div2 { "system_pll2_div2", system_pll2_clk, 2, tree }; + + Root_clock arm_a53_clk_root { "arm_a53_clk_root", root_base(0), m25_ref_clk, arm_pll_clk, system_pll2_div2, system_pll2_clk, system_pll1_clk, system_pll1_div2, audio_pll1_clk, system_pll3_clk, tree }; + Root_clock arm_m4_clk_root { "arm_m4_clk_root", root_base(1), m25_ref_clk, system_pll2_div5, system_pll2_div4, system_pll1_div3, system_pll1_clk, audio_pll1_clk, video_pll1_clk, system_pll3_clk, tree }; + Root_clock vpu_a53_clk_root { "vpu_a53_clk_root", root_base(2), m25_ref_clk, arm_pll_clk, system_pll2_div2, system_pll2_clk, system_pll1_clk, system_pll1_div2, audio_pll1_clk, vpu_pll_clk, tree }; + Root_clock gpu_core_clk_root { "gpu_core_clk_root", root_base(3), m25_ref_clk, gpu_pll_clk, system_pll1_clk, system_pll3_clk, system_pll2_clk, audio_pll1_clk, video_pll1_clk, audio_pll2_clk, tree }; + Root_clock gpu_shader_clk_root { "gpu_shader_clk", root_base(4), m25_ref_clk, gpu_pll_clk, system_pll1_clk, system_pll3_clk, system_pll2_clk, audio_pll1_clk, video_pll1_clk, audio_pll2_clk, tree }; + Root_clock main_axi_clk_root { "main_axi_clk_root", root_base(16), m25_ref_clk, system_pll2_div3, system_pll1_clk, system_pll2_div4, system_pll2_clk, audio_pll1_clk, video_pll1_clk, system_pll1_div8, tree }; + Root_clock enet_axi_clk_root { "enet_axi_clk_root", root_base(17), m25_ref_clk, system_pll1_div3, system_pll1_clk, system_pll2_div4, system_pll2_div5, audio_pll1_clk, video_pll1_clk, system_pll3_clk, tree }; + Root_clock nand_usdhc_bus_clk_root { "nand_usdhc_bus_clk_root", root_base(18), m25_ref_clk, system_pll1_div3, system_pll1_clk, system_pll2_div5, system_pll1_div6, system_pll3_clk, system_pll2_div4, audio_pll1_clk, tree }; + Root_clock vpu_bus_clk_root { "vpu_bus_clk_root", root_base(19), m25_ref_clk, system_pll1_clk, vpu_pll_clk, audio_pll2_clk, system_pll3_clk, system_pll2_clk, system_pll2_div5, system_pll1_div8, tree }; + Root_clock display_axi_clk_root { "display_axi_clk_root", root_base(20), m25_ref_clk, system_pll2_div8, system_pll1_clk, system_pll3_clk, system_pll1_div20, audio_pll2_clk, ext_clk_1, ext_clk_4, tree }; + Root_clock display_apb_clk_root { "display_apb_clk_root", root_base(21), m25_ref_clk, system_pll2_div8, system_pll1_clk, system_pll3_clk, system_pll1_div20, audio_pll2_clk, ext_clk_1, ext_clk_3, tree }; + Root_clock display_rtrm_clk_root { "display_rtrm_clk_root", root_base(22), m25_ref_clk, system_pll1_clk, system_pll2_div5, system_pll1_div2, audio_pll1_clk, video_pll1_clk, ext_clk_2, ext_clk_3, tree }; + Root_clock usb_bus_clk_root { "usb_bus_clk_root", root_base(23), m25_ref_clk, system_pll2_div2, system_pll1_clk, system_pll2_div10, system_pll2_div5, ext_clk_2, ext_clk_4, audio_pll2_clk, tree }; + Root_clock gpu_axi_clk_root { "gpu_axi_clk_root", root_base(24), m25_ref_clk, system_pll1_clk, gpu_pll_clk, system_pll3_clk, system_pll2_clk, audio_pll1_clk, video_pll1_clk, audio_pll2_clk, tree }; + Root_clock gpu_ahb_clk_root { "gpu_ahb_clk_root", root_base(25), m25_ref_clk, system_pll1_clk, gpu_pll_clk, system_pll3_clk, system_pll2_clk, audio_pll1_clk, video_pll1_clk, audio_pll2_clk, tree }; + Root_clock noc_clk_root { "noc_clk_root", root_base(26), m25_ref_clk, system_pll1_clk, system_pll3_clk, system_pll2_clk, system_pll2_div2, audio_pll1_clk, video_pll1_clk, audio_pll2_clk, tree }; + Root_clock noc_apb_clk_root { "noc_apb_clk_root", root_base(27), m25_ref_clk, system_pll1_div2, system_pll3_clk, system_pll2_div3, system_pll2_div5, system_pll1_clk, audio_pll1_clk, video_pll1_clk, tree }; + Root_clock ahb_clk_root { "ahb_clk_root", root_base(32), m25_ref_clk, system_pll1_div6, system_pll1_clk, system_pll1_div2, system_pll2_div8, system_pll3_clk, audio_pll1_clk, video_pll1_clk, tree }; + Root_clock audio_ahb_clk_root { "audio_ahb_clk_root", root_base(34), m25_ref_clk, system_pll2_div2, system_pll1_clk, system_pll2_clk, system_pll2_div6, system_pll3_clk, audio_pll1_clk, video_pll1_clk, tree }; + Root_clock mipi_dsi_esc_rx_clk_root { "mipi_dsi_esc_rx_clk_root", root_base(36), m25_ref_clk, system_pll2_div10, system_pll1_div10, system_pll1_clk, system_pll2_clk, system_pll3_clk, ext_clk_3, audio_pll2_clk, tree }; + Root_clock dram_alt_clk_root { "dram_alt_clk_root", root_base(64), m25_ref_clk, system_pll1_clk, system_pll1_div8, system_pll2_div2, system_pll2_div4, system_pll1_div2, audio_pll1_clk, system_pll1_div3, tree }; + Root_clock dram_apb_clk_root { "dram_apb_clk_root", root_base(65), m25_ref_clk, system_pll2_div5, system_pll1_div20, system_pll1_div5, system_pll1_clk, system_pll3_clk, system_pll2_div4, audio_pll2_clk, tree }; + Root_clock vpu_g1_clk_root { "vpu_g1_clk_root", root_base(66), m25_ref_clk, vpu_pll_clk, system_pll1_clk, system_pll2_clk, system_pll1_div8, system_pll2_div8, system_pll3_clk, audio_pll1_clk, tree }; + Root_clock vpu_g2_clk_root { "vpu_g2_clk_root", root_base(67), m25_ref_clk, vpu_pll_clk, system_pll1_clk, system_pll2_clk, system_pll1_div8, system_pll2_div8, system_pll3_clk, audio_pll1_clk, tree }; + Root_clock display_dtrc_clk_root { "display_dtrc_clk_root", root_base(68), m25_ref_clk, video_pll2_clk, system_pll1_clk, system_pll2_clk, system_pll1_div5, video_pll1_clk, system_pll3_clk, audio_pll2_clk, tree }; + Root_clock display_dc8000_clk_root { "display_dc8000_clk_root", root_base(69), m25_ref_clk, video_pll2_clk, system_pll1_clk, system_pll2_clk, system_pll1_div5, video_pll1_clk, system_pll3_clk, audio_pll2_clk, tree }; + Root_clock pcie1_ctrl_clk_root { "pcie1_ctrl_clk_root", root_base(70), m25_ref_clk, system_pll2_div4, system_pll2_div5, system_pll1_div3, system_pll1_clk, system_pll2_div2, system_pll2_div3, system_pll3_clk, tree }; + Root_clock pcie1_phy_clk_root { "pcie1_phy_clk_root", root_base(71), m25_ref_clk, system_pll2_div10, system_pll2_div2, ext_clk_1, ext_clk_2, ext_clk_3, ext_clk_4, system_pll1_div2, tree }; + Root_clock pcie1_aux_clk_root { "pcie1_aux_clk_root", root_base(72), m25_ref_clk, system_pll2_div5, system_pll2_div20, system_pll3_clk, system_pll2_div10, system_pll1_div10, system_pll1_div5, system_pll1_div4, tree }; + Root_clock dc_pixel_clk_root { "dc_pixel_clk_root", root_base(73), m25_ref_clk, video_pll1_clk, audio_pll2_clk, audio_pll1_clk, system_pll1_clk, system_pll2_clk, system_pll3_clk, ext_clk_4, tree }; + Root_clock lcdif_pixel_clk_root { "lcdif_pixel_clk_root", root_base(74), m25_ref_clk, video_pll1_clk, audio_pll2_clk, audio_pll1_clk, system_pll1_clk, system_pll2_clk, system_pll3_clk, ext_clk_4, tree }; + Root_clock sai1_clk_root { "sai1_clk_root", root_base(75), m25_ref_clk, audio_pll1_clk, audio_pll2_clk, video_pll1_clk, system_pll1_div6, m27_ref_clk, ext_clk_1, ext_clk_2, tree }; + Root_clock sai2_clk_root { "sai2_clk_root", root_base(76), m25_ref_clk, audio_pll1_clk, audio_pll2_clk, video_pll1_clk, system_pll1_div6, m27_ref_clk, ext_clk_2, ext_clk_3, tree }; + Root_clock sai3_clk_root { "sai3_clk_root", root_base(77), m25_ref_clk, audio_pll1_clk, audio_pll2_clk, video_pll1_clk, system_pll1_div6, m27_ref_clk, ext_clk_3, ext_clk_4, tree }; + Root_clock sai4_clk_root { "sai4_clk_root", root_base(78), m25_ref_clk, audio_pll1_clk, audio_pll2_clk, video_pll1_clk, system_pll1_div6, m27_ref_clk, ext_clk_1, ext_clk_2, tree }; + Root_clock sai5_clk_root { "sai5_clk_root", root_base(79), m25_ref_clk, audio_pll1_clk, audio_pll2_clk, video_pll1_clk, system_pll1_div6, m27_ref_clk, ext_clk_2, ext_clk_3, tree }; + Root_clock sai6_clk_root { "sai6_clk_root", root_base(80), m25_ref_clk, audio_pll1_clk, audio_pll2_clk, video_pll1_clk, system_pll1_div6, m27_ref_clk, ext_clk_3, ext_clk_4, tree }; + Root_clock spdif1_clk_root { "spdif1_clk_root", root_base(81), m25_ref_clk, audio_pll1_clk, audio_pll2_clk, video_pll1_clk, system_pll1_div6, m27_ref_clk, ext_clk_2, ext_clk_3, tree }; + Root_clock spdif2_clk_root { "spdif2_clk_root", root_base(82), m25_ref_clk, audio_pll1_clk, audio_pll2_clk, video_pll1_clk, system_pll1_div6, m27_ref_clk, ext_clk_3, ext_clk_4, tree }; + Root_clock enet_ref_clk_root { "enet_ref_clk_root", root_base(83), m25_ref_clk, system_pll2_div8, system_pll2_div20, system_pll2_div10, system_pll1_div5, audio_pll1_clk, video_pll1_clk, ext_clk_4, tree }; + Root_clock enet_timer_clk_root { "enet_timer_clk_root", root_base(84), m25_ref_clk, system_pll2_div10, audio_pll1_clk, ext_clk_1, ext_clk_2, ext_clk_3, ext_clk_4, video_pll1_clk, tree }; + Root_clock enet_phy_ref_clk_root { "enet_phy_ref_clk_root", root_base(85), m25_ref_clk, system_pll2_div20, system_pll2_div8, system_pll2_div5, system_pll2_div2, audio_pll1_clk, video_pll1_clk, audio_pll2_clk, tree }; + Root_clock nand_clk_root { "nand_clk_root", root_base(86), m25_ref_clk, system_pll2_div2, audio_pll1_clk, system_pll1_div2, audio_pll2_clk, system_pll3_clk, system_pll2_div4, video_pll1_clk, tree }; + Root_clock qspi_clk_root { "qspi_clk_root", root_base(87), m25_ref_clk, system_pll1_div2, system_pll1_clk, system_pll2_div2, audio_pll2_clk, system_pll1_div3, system_pll3_clk, system_pll1_div8, tree }; + Root_clock usdhc1_clk_root { "usdhc1_clk_root", root_base(88), m25_ref_clk, system_pll1_div2, system_pll1_clk, system_pll2_div2, system_pll3_clk, system_pll1_div3, audio_pll2_clk, system_pll1_div8, tree }; + Root_clock usdhc2_clk_root { "usdhc2_clk_root", root_base(89), m25_ref_clk, system_pll1_div2, system_pll1_clk, system_pll2_div2, system_pll3_clk, system_pll1_div3, audio_pll2_clk, system_pll1_div8, tree }; + Root_clock i2c1_clk_root { "i2c1_clk_root", root_base(90), m25_ref_clk, system_pll1_div5, system_pll2_div20, system_pll3_clk, audio_pll1_clk, video_pll1_clk, audio_pll2_clk, system_pll1_div6, tree }; + Root_clock i2c2_clk_root { "i2c2_clk_root", root_base(91), m25_ref_clk, system_pll1_div5, system_pll2_div20, system_pll3_clk, audio_pll1_clk, video_pll1_clk, audio_pll2_clk, system_pll1_div6, tree }; + Root_clock i2c3_clk_root { "i2c3_clk_root", root_base(92), m25_ref_clk, system_pll1_div5, system_pll2_div20, system_pll3_clk, audio_pll1_clk, video_pll1_clk, audio_pll2_clk, system_pll1_div6, tree }; + Root_clock i2c4_clk_root { "i2c4_clk_root", root_base(93), m25_ref_clk, system_pll1_div5, system_pll2_div20, system_pll3_clk, audio_pll1_clk, video_pll1_clk, audio_pll2_clk, system_pll1_div6, tree }; + Root_clock uart1_clk_root { "uart1_clk_root", root_base(94), m25_ref_clk, system_pll1_div10, system_pll2_div5, system_pll2_div10, system_pll3_clk, ext_clk_2, ext_clk_4, audio_pll2_clk, tree }; + Root_clock uart2_clk_root { "uart2_clk_root", root_base(95), m25_ref_clk, system_pll1_div10, system_pll2_div5, system_pll2_div10, system_pll3_clk, ext_clk_2, ext_clk_3, audio_pll2_clk, tree }; + Root_clock uart3_clk_root { "uart3_clk_root", root_base(96), m25_ref_clk, system_pll1_div10, system_pll2_div5, system_pll2_div10, system_pll3_clk, ext_clk_2, ext_clk_4, audio_pll2_clk, tree }; + Root_clock uart4_clk_root { "uart4_clk_root", root_base(97), m25_ref_clk, system_pll1_div10, system_pll2_div5, system_pll2_div10, system_pll3_clk, ext_clk_2, ext_clk_3, audio_pll2_clk, tree }; + Root_clock usb_core_ref_clk_root { "usb_core_ref_clk_root", root_base(98), m25_ref_clk, system_pll1_div8, system_pll1_div20, system_pll2_div10, system_pll2_div5, ext_clk_2, ext_clk_3, audio_pll2_clk, tree }; + Root_clock usb_phy_ref_clk_root { "usb_phy_ref_clk_root", root_base(99), m25_ref_clk, system_pll1_div8, system_pll1_div20, system_pll2_div10, system_pll2_div5, ext_clk_2, ext_clk_3, audio_pll2_clk, tree }; + Root_clock gic_clk_root { "gic_clk_root", root_base(100), m25_ref_clk, system_pll2_div5, system_pll1_div20, system_pll2_div10, system_pll1_clk, ext_clk_2, ext_clk_4, audio_pll2_clk, tree }; + Root_clock ecspi1_clk_root { "ecspi1_clk_root", root_base(101), m25_ref_clk, system_pll2_div5, system_pll1_div20, system_pll1_div5, system_pll1_clk, system_pll3_clk, system_pll2_div4, audio_pll2_clk, tree }; + Root_clock ecspi2_clk_root { "ecspi2_clk_root", root_base(102), m25_ref_clk, system_pll2_div5, system_pll1_div20, system_pll1_div5, system_pll1_clk, system_pll3_clk, system_pll2_div4, audio_pll2_clk, tree }; + Root_clock pwm1_clk_root { "pwm1_clk_root", root_base(103), m25_ref_clk, system_pll2_div10, system_pll1_div5, system_pll1_div20, system_pll3_clk, ext_clk_1, system_pll1_div10, video_pll1_clk, tree }; + Root_clock pwm2_clk_root { "pwm2_clk_root", root_base(104), m25_ref_clk, system_pll2_div10, system_pll1_div5, system_pll1_div20, system_pll3_clk, ext_clk_1, system_pll1_div10, video_pll1_clk, tree }; + Root_clock pwm3_clk_root { "pwm3_clk_root", root_base(105), m25_ref_clk, system_pll2_div10, system_pll1_div5, system_pll1_div20, system_pll3_clk, ext_clk_2, system_pll1_div10, video_pll1_clk, tree }; + Root_clock pwm4_clk_root { "pwm4_clk_root", root_base(106), m25_ref_clk, system_pll2_div10, system_pll1_div5, system_pll1_div20, system_pll3_clk, ext_clk_2, system_pll1_div10, video_pll1_clk, tree }; + Root_clock gpt1_clk_root { "gpt1_clk_root", root_base(107), m25_ref_clk, system_pll2_div10, system_pll1_div2, system_pll1_div20, video_pll1_clk, system_pll1_div10, audio_pll1_clk, ext_clk_1, tree }; + Root_clock gpt2_clk_root { "gpt2_clk_root", root_base(108), m25_ref_clk, system_pll2_div10, system_pll1_div2, system_pll1_div20, video_pll1_clk, system_pll1_div10, audio_pll1_clk, ext_clk_2, tree }; + Root_clock gpt3_clk_root { "gpt3_clk_root", root_base(109), m25_ref_clk, system_pll2_div10, system_pll1_div2, system_pll1_div20, video_pll1_clk, system_pll1_div10, audio_pll1_clk, ext_clk_3, tree }; + Root_clock gpt4_clk_root { "gpt4_clk_root", root_base(110), m25_ref_clk, system_pll2_div10, system_pll1_div2, system_pll1_div20, video_pll1_clk, system_pll1_div10, audio_pll1_clk, ext_clk_1, tree }; + Root_clock gpt5_clk_root { "gpt5_clk_root", root_base(111), m25_ref_clk, system_pll2_div10, system_pll1_div2, system_pll1_div20, video_pll1_clk, system_pll1_div10, audio_pll1_clk, ext_clk_2, tree }; + Root_clock gpt6_clk_root { "gpt6_clk_root", root_base(112), m25_ref_clk, system_pll2_div10, system_pll1_div2, system_pll1_div20, video_pll1_clk, system_pll1_div10, audio_pll1_clk, ext_clk_3, tree }; + Root_clock trace_clk_root { "trace_clk_root", root_base(113), m25_ref_clk, system_pll1_div6, system_pll1_div5, vpu_pll_clk, system_pll2_div8, system_pll3_clk, ext_clk_1, ext_clk_3, tree }; + Root_clock wdog_clk_root { "wdog_clk_root", root_base(114), m25_ref_clk, system_pll1_div6, system_pll1_div5, vpu_pll_clk, system_pll2_div8, system_pll3_clk, system_pll1_div10, system_pll2_div6, tree }; + Root_clock wrclk_clk_root { "wrclk_clk_root", root_base(115), m25_ref_clk, system_pll1_div20, vpu_pll_clk, system_pll3_clk, system_pll2_div5, system_pll1_div3, system_pll2_div2, system_pll1_div8, tree }; + Root_clock ipp_do_clko1clk_root { "ipp_do_clko1_clk_root", root_base(116), m25_ref_clk, system_pll1_clk, m27_ref_clk, system_pll1_div4, audio_pll2_clk, system_pll2_div2, vpu_pll_clk, system_pll1_div10, tree }; + Root_clock ipp_do_clko2_clk_root { "ipp_do_clko2_clk_root", root_base(117), m25_ref_clk, system_pll2_div5, system_pll1_div2, system_pll2_div6, system_pll3_clk, audio_pll1_clk, video_pll1_clk, k32_ref_clk, tree }; + Root_clock mipi_dsi_core_clk_root { "mipi_dsi_core_clk_root", root_base(118), m25_ref_clk, system_pll1_div3, system_pll2_div4, system_pll1_clk, system_pll2_clk, system_pll3_clk, audio_pll2_clk, video_pll1_clk, tree }; + Root_clock mipi_dsi_phy_ref_clk_root { "mipi_dsi_phy_ref_clk_root", root_base(119), m25_ref_clk, system_pll2_div8, system_pll2_div10, system_pll1_clk, system_pll2_clk, ext_clk_2, audio_pll2_clk, video_pll1_clk, tree }; + Root_clock mipi_dsi_dbi_clk_root { "mipi_dsi_dbi_clk_root", root_base(120), m25_ref_clk, system_pll1_div3, system_pll2_div10, system_pll1_clk, system_pll2_clk, system_pll3_clk, audio_pll2_clk, video_pll1_clk, tree }; + Root_clock old_mipi_dsi_esc_clk_root { "old_mipi_dsi_esc_clk_root", root_base(121), m25_ref_clk, system_pll2_div10, system_pll1_div10, system_pll1_clk, system_pll2_clk, system_pll3_clk, ext_clk_3, audio_pll2_clk, tree }; + Root_clock mipi_csi1_core_clk_root { "mipi_csi1_core_clk_root", root_base(122), m25_ref_clk, system_pll1_div3, system_pll2_div4, system_pll1_clk, system_pll2_clk, system_pll3_clk, audio_pll2_clk, video_pll1_clk, tree }; + Root_clock mipi_csi1_phy_ref_clk_root { "mipi_csi1_phy_ref_clk_root", root_base(123), m25_ref_clk, system_pll2_div3, system_pll2_div10, system_pll1_clk, system_pll2_clk, ext_clk_2, audio_pll2_clk, video_pll1_clk, tree }; + Root_clock mipi_csi1_esc_clk_root { "mipi_csi1_esc_clk_root", root_base(124), m25_ref_clk, system_pll2_div10, system_pll1_div10, system_pll1_clk, system_pll2_clk, system_pll3_clk, ext_clk_3, audio_pll2_clk, tree }; + Root_clock mipi_csi2_core_clk_root { "mipi_csi2_core_clk_root", root_base(125), m25_ref_clk, system_pll1_div3, system_pll2_div4, system_pll1_clk, system_pll2_clk, system_pll3_clk, audio_pll2_clk, video_pll1_clk, tree }; + Root_clock mipi_csi2_phy_ref_clk_root { "mipi_csi2_phy_ref_clk_root", root_base(126), m25_ref_clk, system_pll2_div3, system_pll2_div10, system_pll1_clk, system_pll2_clk, ext_clk_2, audio_pll2_clk, video_pll1_clk, tree }; + Root_clock mipi_csi2_esc_clk_root { "mipi_csi2_esc_clk_root", root_base(127), m25_ref_clk, system_pll2_div10, system_pll1_div10, system_pll1_clk, system_pll2_clk, system_pll3_clk, ext_clk_3, audio_pll2_clk, tree }; + Root_clock pcie2_ctrl_clk_root { "pcie2_ctrl_clk_root", root_base(128), m25_ref_clk, system_pll2_div4, system_pll2_div5, system_pll1_div3, system_pll1_clk, system_pll2_div2, system_pll2_div3, system_pll3_clk, tree }; + Root_clock pcie2_phy_clk_root { "pcie2_phy_clk_root", root_base(129), m25_ref_clk, system_pll2_div10, system_pll2_div2, ext_clk_1, ext_clk_2, ext_clk_3, ext_clk_4, system_pll1_div2, tree }; + Root_clock pcie2_aux_clk_root { "pcie2_aux_clk_root", root_base(130), m25_ref_clk, system_pll2_div5, system_pll2_div20, system_pll3_clk, system_pll2_div10, system_pll1_div10, system_pll1_div5, system_pll1_div4, tree }; + Root_clock ecspi3_clk_root { "ecspi3_clk_root", root_base(131), m25_ref_clk, system_pll2_div5, system_pll1_div20, system_pll1_div5, system_pll1_clk, system_pll3_clk, system_pll2_div4, audio_pll2_clk, tree }; + Root_clock old_mipi_dsi_esc_rx_clk_root { "old_mipi_dsi_esc_rx_clk_root", root_base(132), m25_ref_clk, system_pll2_div10, system_pll1_div10, system_pll1_clk, system_pll2_clk, system_pll3_clk, ext_clk_3, audio_pll2_clk, tree }; + Root_clock display_hdmi_clk_root { "display_hdmi_clk_root", root_base(133), m25_ref_clk, system_pll1_div4, system_pll2_div5, vpu_pll_clk, system_pll1_clk, system_pll2_clk, system_pll3_clk, ext_clk_4, tree }; + + Root_clock_divider ipg_clk_root { "ipg_clk_root", root_base(33), ahb_clk_root, tree }; + Root_clock_divider ipg_audio_clk_root { "ipg_audio_clk_root", root_base(35), audio_ahb_clk_root, tree }; + Root_clock_divider mipi_dsi_esc_clk_root { "mipi_dsi_esc_clk_root", root_base(37), mipi_dsi_esc_rx_clk_root, tree }; + + Gate ecspi1_gate { "ecspi1_gate", gate_base(7), ecspi1_clk_root, tree }; + Gate ecspi2_gate { "ecspi2_gate", gate_base(8), ecspi2_clk_root, tree }; + Gate ecspi3_gate { "ecspi3_gate", gate_base(9), ecspi3_clk_root, tree }; + Gate enet1_gate { "enet1_gate", gate_base(10), enet_axi_clk_root, tree }; + Gate gpt1_gate { "gpt1_gate", gate_base(16), gpt1_clk_root, tree }; + Gate i2c1_gate { "i2c1_gate", gate_base(23), i2c1_clk_root, tree }; + Gate i2c2_gate { "i2c2_gate", gate_base(24), i2c2_clk_root, tree }; + Gate i2c3_gate { "i2c3_gate", gate_base(25), i2c3_clk_root, tree }; + Gate i2c4_gate { "i2c4_gate", gate_base(26), i2c4_clk_root, tree }; + Gate mu_gate { "mu_gate", gate_base(33), ipg_clk_root, tree }; + Gate ocotp_gate { "ocotp_gate", gate_base(34), ipg_clk_root, tree }; + Gate pcie_gate { "pcie_gate", gate_base(37), pcie1_ctrl_clk_root, tree }; + Gate pwm1_gate { "pwm1_gate", gate_base(40), pwm1_clk_root, tree }; + Gate pwm2_gate { "pwm2_gate", gate_base(41), pwm2_clk_root, tree }; + Gate pwm3_gate { "pwm3_gate", gate_base(42), pwm3_clk_root, tree }; + Gate pwm4_gate { "pwm4_gate", gate_base(43), pwm4_clk_root, tree }; + Gate qspi_gate { "qspi_gate", gate_base(47), qspi_clk_root, tree }; + Gate nand_gate { "nand_gate", gate_base(48), nand_clk_root, tree }; + Gate sai1_gate { "sai1_gate", gate_base(51), sai1_clk_root, tree }; + Gate sai2_gate { "sai2_gate", gate_base(52), sai2_clk_root, tree }; + Gate sai3_gate { "sai3_gate", gate_base(53), sai3_clk_root, tree }; + Gate sai4_gate { "sai4_gate", gate_base(54), sai4_clk_root, tree }; + Gate sai5_gate { "sai5_gate", gate_base(55), sai5_clk_root, tree }; + Gate sai6_gate { "sai6_gate", gate_base(56), sai6_clk_root, tree }; + Gate sdma1_gate { "sdma1_gate", gate_base(58), ipg_clk_root, tree }; + Gate sdma2_gate { "sdma2_gate", gate_base(59), ipg_audio_clk_root, tree }; + Gate uart1_gate { "uart1_gate", gate_base(73), uart1_clk_root, tree }; + Gate uart2_gate { "uart2_gate", gate_base(74), uart2_clk_root, tree }; + Gate uart3_gate { "uart3_gate", gate_base(75), uart3_clk_root, tree }; + Gate uart4_gate { "uart4_gate", gate_base(76), uart4_clk_root, tree }; + Gate usb_ctrl1_gate { "usb_ctrl1_gate", gate_base(77), usb_core_ref_clk_root, tree }; + Gate usb_ctrl2_gate { "usb_ctrl2_gate", gate_base(78), usb_core_ref_clk_root, tree }; + Gate usb_phy1_gate { "usb_phy1_gate", gate_base(79), usb_phy_ref_clk_root, tree }; + Gate usb_phy2_gate { "usb_phy2_gate", gate_base(80), usb_phy_ref_clk_root, tree }; + Gate usdhc1_gate { "usdhc1_gate", gate_base(81), usdhc1_clk_root, tree }; + Gate usdhc2_gate { "usdhc2_gate", gate_base(82), usdhc2_clk_root, tree }; + Gate wdog1_gate { "wdog1_gate", gate_base(83), wdog_clk_root, tree }; + Gate wdog2_gate { "wdog2_gate", gate_base(84), wdog_clk_root, tree }; + Gate wdog3_gate { "wdog3_gate", gate_base(85), wdog_clk_root, tree }; + Gate va53_gate { "va53_gate", gate_base(86), vpu_g1_clk_root, tree }; + Gate gpu_gate { "gpu_gate", gate_base(87), gpu_core_clk_root, tree }; + Gate vp9_gate { "vp9_gate", gate_base(90), vpu_g2_clk_root, tree }; + Gate display_gate { "display_gate", gate_base(93), display_dc8000_clk_root, tree }; + Gate tempsensor_gate { "tempsensor_gate", gate_base(98), ipg_clk_root, tree }; + Gate vpu_dec_gate { "vpu_dec_gate", gate_base(99), vpu_bus_clk_root, tree }; + Gate pcie2_gate { "pcie2_gate", gate_base(100), pcie2_ctrl_clk_root, tree }; + Gate mipi_csi1_gate { "mipi_csi1_gate", gate_base(101), mipi_csi1_core_clk_root, tree }; + Gate mipi_csi2_gate { "mipi_csi2_gate", gate_base(102), mipi_csi2_core_clk_root, tree }; +}; diff --git a/repos/os/src/drivers/platform/imx8mq/clock.h b/repos/os/src/drivers/platform/imx8mq/clock.h new file mode 100644 index 0000000000..d9c8fe07c5 --- /dev/null +++ b/repos/os/src/drivers/platform/imx8mq/clock.h @@ -0,0 +1,120 @@ +/* + * \brief Clock tree for platform driver + * \author Stefan Kalkowski + * \date 2020-06-12 + */ + +/* + * Copyright (C) 2020 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 + +namespace Driver { + template class Avl_string_element; + class Clock; + class Fixed_clock; + class Fixed_divider; + + using namespace Genode; +} + + +template +class Driver::Avl_string_element : public String, + public Avl_string_base +{ + T & _object; + + public: + + Avl_string_element(String name, T & o) + : String(name), + Avl_string_base(this->string()), + _object(o) {} + + String name() const { return *this; } + T & object() const { return _object; } +}; + + +class Driver::Clock +{ + protected: + + enum { NAME_LEN = 64 }; + + using Node = Avl_string_element; + + Node _tree_elem; + + /* + * Noncopyable + */ + Clock(Clock const &); + Clock &operator = (Clock const &); + + public: + + using Name = Genode::String; + using Clock_tree = Avl_tree; + using Clock_tree_element = Avl_string_element; + + Clock(Name name, + Clock_tree & tree) + : _tree_elem(name, *this) { tree.insert(&_tree_elem); } + + virtual ~Clock() {} + + virtual void set_rate(unsigned long rate) = 0; + virtual unsigned long get_rate() const = 0; + virtual void enable() {} + virtual void disable() {} + virtual void set_parent(Name) {} + + Name name() const { return _tree_elem.name(); } +}; + + +class Driver::Fixed_clock : public Driver::Clock +{ + private: + + unsigned long _rate; + + public: + + Fixed_clock(Name name, + unsigned long rate, + Clock_tree & tree) + : Clock(name, tree), _rate(rate) {} + + void set_rate(unsigned long) override {} + unsigned long get_rate() const override { return _rate; } +}; + + +class Driver::Fixed_divider : public Driver::Clock +{ + private: + + Clock & _parent; + unsigned _divider; + + public: + + Fixed_divider(Name name, + Clock & parent, + unsigned divider, + Clock_tree & tree) + : Clock(name, tree), _parent(parent), _divider(divider) {} + + void set_rate(unsigned long) override {} + unsigned long get_rate() const override { + return _parent.get_rate() / _divider; } +}; diff --git a/repos/os/src/drivers/platform/imx8mq/device_model_policy.cc b/repos/os/src/drivers/platform/imx8mq/device_model_policy.cc new file mode 100644 index 0000000000..f534e21d48 --- /dev/null +++ b/repos/os/src/drivers/platform/imx8mq/device_model_policy.cc @@ -0,0 +1,90 @@ +/* + * \brief Platform driver - Device model policy for i.MX + * \author Stefan Kalkowski + * \date 2020-08-16 + */ + +/* + * Copyright (C) 2020 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. + */ + +#include +#include + +using Driver::Device_model; +using Driver::Device; +using Driver::Imx_device; + +void Device_model::destroy_element(Device & dev) +{ + Imx_device & device = static_cast(dev); + + { + Irq_update_policy policy(_env.heap); + device._irq_list.destroy_all_elements(policy); + } + + { + Io_mem_update_policy policy(_env.heap); + device._io_mem_list.destroy_all_elements(policy); + } + + { + Property_update_policy policy(_env.heap); + device._property_list.destroy_all_elements(policy); + } + + { + Clock_update_policy policy(_env.heap); + device._clock_list.destroy_all_elements(policy); + } + + { + Power_domain_update_policy policy(_env.heap); + device._power_domain_list.destroy_all_elements(policy); + } + + Genode::destroy(_env.heap, &device); +} + + +Device & Device_model::create_element(Genode::Xml_node node) +{ + Device::Name name = node.attribute_value("name", Device::Name()); + return *(new (_env.heap) Imx_device(name)); +} + + +void Device_model::update_element(Device & dev, + Genode::Xml_node node) +{ + Imx_device & device = static_cast(dev); + + { + Irq_update_policy policy(_env.heap); + device._irq_list.update_from_xml(policy, node); + } + + { + Io_mem_update_policy policy(_env.heap); + device._io_mem_list.update_from_xml(policy, node); + } + + { + Property_update_policy policy(_env.heap); + device._property_list.update_from_xml(policy, node); + } + + { + Clock_update_policy policy(_env.heap); + device._clock_list.update_from_xml(policy, node); + } + + { + Power_domain_update_policy policy(_env.heap); + device._power_domain_list.update_from_xml(policy, node); + } +} diff --git a/repos/os/src/drivers/platform/imx8mq/env.h b/repos/os/src/drivers/platform/imx8mq/env.h new file mode 100644 index 0000000000..0e59716ada --- /dev/null +++ b/repos/os/src/drivers/platform/imx8mq/env.h @@ -0,0 +1,45 @@ +/* + * \brief Platform driver for ARM + * \author Stefan Kalkowski + * \date 2020-04-12 + */ + +/* + * Copyright (C) 2020 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. + */ + +#ifndef _SRC__DRIVERS__PLATFORM__SPEC__ARM__ENV_H_ +#define _SRC__DRIVERS__PLATFORM__SPEC__ARM__ENV_H_ + +#include +#include +#include + +#include +#include +#include + +namespace Driver { + using namespace Genode; + + struct Env; +}; + + +struct Driver::Env +{ + Genode::Env & env; + Heap heap { env.ram(), env.rm() }; + Sliced_heap sliced_heap { env.ram(), env.rm() }; + Attached_rom_dataspace config { env, "config" }; + Ccm ccm { env }; + Gpc gpc { env }; + Device_model devices { *this }; + + Env(Genode::Env &env) : env(env) { } +}; + +#endif /* _SRC__DRIVERS__PLATFORM__SPEC__ARM__ENV_H_ */ diff --git a/repos/os/src/drivers/platform/imx8mq/gpc.h b/repos/os/src/drivers/platform/imx8mq/gpc.h new file mode 100644 index 0000000000..94efecb3b1 --- /dev/null +++ b/repos/os/src/drivers/platform/imx8mq/gpc.h @@ -0,0 +1,103 @@ +/* + * \brief Global power controller for i.MX8 + * \author Stefan Kalkowski + * \date 2020-06-12 + */ + +/* + * Copyright (C) 2020 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 +#include + +struct Gpc +{ + enum Pu { + MIPI = 0, + PCIE_1 = 1, + USB_OTG_1 = 2, + USB_OTG_2 = 3, + GPU = 4, + VPU = 5, + HDMI = 6, + DISP = 7, + CSI_1 = 8, + CSI_2 = 9, + PCIE_2 = 10, + INVALID, + }; + + enum { + SIP_SERVICE_FUNC = 0xc2000000, + GPC_PM_DOMAIN = 0x3, + ON = 1, + OFF = 0 + }; + + Genode::Env & env; + + Pu pu(Genode::String<64> name) + { + if (name == "mipi") { return MIPI; } + if (name == "pcie_1") { return PCIE_1; } + if (name == "usb_otg_1") { return USB_OTG_1; } + if (name == "usb_otg_2") { return USB_OTG_2; } + if (name == "gpu") { return GPU; } + if (name == "vpu") { return VPU; } + if (name == "hdmi") { return HDMI; } + if (name == "disp") { return DISP; } + if (name == "csi_1") { return CSI_1; } + if (name == "csi_2") { return CSI_2; } + if (name == "pcie_2") { return PCIE_2; } + return INVALID; + } + + void enable(Genode::String<64> name) + { + Genode::Pd_session::Managing_system_state state; + state.r[0] = SIP_SERVICE_FUNC; + state.r[1] = GPC_PM_DOMAIN; + state.r[2] = pu(name); + state.r[3] = ON; + + if (state.r[2] == INVALID) { + Genode::warning("Power domain ", name.string(), " is not valid!"); + return; + } + + env.pd().managing_system(state); + } + + void disable(Genode::String<64> name) + { + Genode::Pd_session::Managing_system_state state; + state.r[0] = SIP_SERVICE_FUNC; + state.r[1] = GPC_PM_DOMAIN; + state.r[2] = pu(name); + state.r[3] = OFF; + + if (state.r[2] == INVALID) { + Genode::warning("Power domain ", name.string(), " is not valid!"); + return; + } + + env.pd().managing_system(state); + } + + Gpc(Genode::Env & env) : env(env) + { + for (unsigned domain = MIPI; domain <= PCIE_2; domain++) { + Genode::Pd_session::Managing_system_state state; + state.r[0] = SIP_SERVICE_FUNC; + state.r[1] = GPC_PM_DOMAIN; + state.r[2] = domain; + state.r[3] = OFF; + } + }; +}; diff --git a/repos/os/src/drivers/platform/imx8mq/imx_device.cc b/repos/os/src/drivers/platform/imx8mq/imx_device.cc new file mode 100644 index 0000000000..adaebebf87 --- /dev/null +++ b/repos/os/src/drivers/platform/imx8mq/imx_device.cc @@ -0,0 +1,76 @@ +/* + * \brief Platform driver - Device abstraction for i.MX + * \author Stefan Kalkowski + * \date 2020-08-17 + */ + +/* + * Copyright (C) 2020 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. + */ + +#include +#include +#include + + +bool Driver::Imx_device::acquire(Driver::Session_component & sc) +{ + bool ret = Driver::Device::acquire(sc); + + if (ret) { + _power_domain_list.for_each([&] (Power_domain & p) { + sc.env().gpc.enable(p.name); }); + _clock_list.for_each([&] (Clock & c) { + Avl_string_base * asb = + sc.env().ccm.tree.first()->find_by_name(c.name.string()); + if (!asb) { + Genode::warning("Clock ", c.name, " is unknown! "); + return; + } + Driver::Clock & clock = + static_cast(asb)->object(); + if (c.parent.valid()) { clock.set_parent(c.parent); } + if (c.rate) { clock.set_rate(c.rate); } + clock.enable(); + }); + + sc.update_devices_rom(); + } + + return ret; +} + + +void Driver::Imx_device::release(Session_component & sc) +{ + _power_domain_list.for_each([&] (Power_domain & p) { + sc.env().gpc.disable(p.name); }); + _clock_list.for_each([&] (Clock & c) { + Avl_string_base * asb = + sc.env().ccm.tree.first()->find_by_name(c.name.string()); + if (!asb) { return; } + static_cast(asb)->object().disable(); + }); + + return Driver::Device::release(sc); +} + + +void Driver::Imx_device::_report_platform_specifics(Genode::Xml_generator & xml, + Driver::Session_component & sc) +{ + _clock_list.for_each([&] (Clock & c) { + Avl_string_base * asb = + sc.env().ccm.tree.first()->find_by_name(c.name.string()); + if (!asb || !c.driver_name.valid()) { return; } + Driver::Clock & clock = + static_cast(asb)->object(); + xml.node("clock", [&] () { + xml.attribute("rate", clock.get_rate()); + xml.attribute("name", c.driver_name); + }); + }); +} diff --git a/repos/os/src/drivers/platform/imx8mq/imx_device.h b/repos/os/src/drivers/platform/imx8mq/imx_device.h new file mode 100644 index 0000000000..cff0cf7ace --- /dev/null +++ b/repos/os/src/drivers/platform/imx8mq/imx_device.h @@ -0,0 +1,140 @@ +/* + * \brief Platform driver - Device abstraction for i.MX + * \author Stefan Kalkowski + * \date 2020-08-17 + */ + +/* + * Copyright (C) 2020 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. + */ + +#ifndef _SRC__DRIVERS__PLATFORM__IMX8MQ__IMX_DEVICE_H_ +#define _SRC__DRIVERS__PLATFORM__IMX8MQ__IMX_DEVICE_H_ + +#include + +namespace Driver { + using namespace Genode; + + class Imx_device; + struct Clock_update_policy; + struct Power_domain_update_policy; +} + + +class Driver::Imx_device : public Driver::Device +{ + public: + + struct Clock : List_model::Element + { + using Name = Genode::String<64>; + + Name name; + Name parent; + Name driver_name; + unsigned long rate; + + Clock(Name name, + Name parent, + Name driver_name, + unsigned long rate) + : name(name), parent(parent), + driver_name(driver_name), rate(rate) {} + }; + + struct Power_domain : List_model::Element + { + using Name = Genode::String<64>; + + Name name; + + Power_domain(Name name) : name(name) {} + }; + + bool acquire(Session_component &) override; + void release(Session_component &) override; + + Imx_device(Device::Name name) : Device(name) {} + + protected: + + friend class Driver::Device_model; + friend class List_model; + + void _report_platform_specifics(Xml_generator &, + Session_component &) override; + + List_model _clock_list {}; + List_model _power_domain_list {}; +}; + + +struct Driver::Clock_update_policy +: Genode::List_model::Update_policy +{ + Genode::Allocator & alloc; + + Clock_update_policy(Genode::Allocator & alloc) : alloc(alloc) {} + + void destroy_element(Element & clock) { + Genode::destroy(alloc, &clock); } + + Element & create_element(Genode::Xml_node node) + { + Element::Name name = node.attribute_value("name", Element::Name()); + Element::Name parent = node.attribute_value("parent", Element::Name()); + Element::Name driver = node.attribute_value("driver_name", Element::Name()); + unsigned long rate = node.attribute_value("rate", 0); + return *(new (alloc) Element(name, parent, driver, rate)); + } + + void update_element(Element &, Genode::Xml_node) {} + + static bool element_matches_xml_node(Element const & clock, Genode::Xml_node node) + { + Element::Name name = node.attribute_value("name", Element::Name()); + return name == clock.name; + } + + static bool node_is_element(Genode::Xml_node node) + { + return node.has_type("clock"); + } +}; + + +struct Driver::Power_domain_update_policy +: Genode::List_model::Update_policy +{ + Genode::Allocator & alloc; + + Power_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("power-domain"); + } +}; + +#endif /* _SRC__DRIVERS__PLATFORM__IMX8MQ__IMX_DEVICE_H_ */ diff --git a/repos/os/src/drivers/platform/imx8mq/target.mk b/repos/os/src/drivers/platform/imx8mq/target.mk new file mode 100644 index 0000000000..284a7785cc --- /dev/null +++ b/repos/os/src/drivers/platform/imx8mq/target.mk @@ -0,0 +1,15 @@ +TARGET = imx8mq_platform_drv +REQUIRES = arm_v8 +SRC_CC = ccm.cc +SRC_CC += device.cc +SRC_CC += device_component.cc +SRC_CC += device_model_policy.cc +SRC_CC += imx_device.cc +SRC_CC += main.cc +SRC_CC += session_component.cc +SRC_CC += root.cc +INC_DIR = $(PRG_DIR) $(REP_DIR)/src/drivers/platform/spec/arm +LIBS = base + +vpath %.cc $(PRG_DIR) +vpath %.cc $(REP_DIR)/src/drivers/platform/spec/arm diff --git a/repos/os/src/drivers/platform/spec/arm/device.cc b/repos/os/src/drivers/platform/spec/arm/device.cc index 4317398e05..ef2e9ccc30 100644 --- a/repos/os/src/drivers/platform/spec/arm/device.cc +++ b/repos/os/src/drivers/platform/spec/arm/device.cc @@ -19,8 +19,6 @@ Driver::Device::Name Driver::Device::name() const { return _name; } bool Driver::Device::acquire(Session_component & sc) { - using namespace Genode; - if (_session.valid() && _session != sc.label()) { return false; } /** @@ -50,18 +48,18 @@ void Driver::Device::release(Session_component & sc) { if (_session != sc.label()) { return; } - sc.replenish(Genode::Cap_quota{_cap_quota_required()}); - sc.replenish(Genode::Ram_quota{_ram_quota_required()}); + sc.replenish(Cap_quota{_cap_quota_required()}); + sc.replenish(Ram_quota{_ram_quota_required()}); _io_mem_list.for_each([&] (Io_mem & io_mem) { if (io_mem.io_mem) { - Genode::destroy(sc.heap(), io_mem.io_mem); + destroy(sc.heap(), io_mem.io_mem); } }); _irq_list.for_each([&] (Irq & irq) { if (irq.irq) { - Genode::destroy(sc.heap(), irq.irq); + destroy(sc.heap(), irq.irq); } }); @@ -72,7 +70,7 @@ void Driver::Device::release(Session_component & sc) Genode::Irq_session_capability Driver::Device::irq(unsigned idx, Session_component & sc) { - Genode::Irq_session_capability cap; + Irq_session_capability cap; if (_session != sc.label()) { return cap; } @@ -83,7 +81,7 @@ Genode::Irq_session_capability Driver::Device::irq(unsigned idx, if (!irq.irq) { irq.irq = new (sc.heap()) - Genode::Irq_connection(sc.env(), irq.number); + Irq_connection(sc.env().env, irq.number); } cap = irq.irq->cap(); }); @@ -93,10 +91,10 @@ Genode::Irq_session_capability Driver::Device::irq(unsigned idx, Genode::Io_mem_session_capability -Driver::Device::io_mem(unsigned idx, Genode::Cache_attribute attr, +Driver::Device::io_mem(unsigned idx, Cache_attribute attr, Session_component & sc) { - Genode::Io_mem_session_capability cap; + Io_mem_session_capability cap; if (_session != sc.label()) return cap; @@ -107,8 +105,8 @@ Driver::Device::io_mem(unsigned idx, Genode::Cache_attribute attr, if (!io_mem.io_mem) { io_mem.io_mem = new (sc.heap()) - Genode::Io_mem_connection(sc.env(), io_mem.base, io_mem.size, - (attr == Genode::WRITE_COMBINED)); + Io_mem_connection(sc.env().env, io_mem.base, io_mem.size, + (attr == WRITE_COMBINED)); } cap = io_mem.io_mem->cap(); }); @@ -117,32 +115,50 @@ Driver::Device::io_mem(unsigned idx, Genode::Cache_attribute attr, } -void Driver::Device::report(Genode::Xml_generator & xml) +void Driver::Device::report(Xml_generator & xml, Session_component & sc) { + unsigned io_mem_id = 0; + unsigned irq_id = 0; + + static constexpr addr_t page_off_mask = (addr_t)((1 << 12) - 1); + xml.node("device", [&] () { xml.attribute("name", name()); + _io_mem_list.for_each([&] (Io_mem & io_mem) { + xml.node("io_mem", [&] () { + xml.attribute("id", io_mem_id++); + xml.attribute("size", io_mem.size); + xml.attribute("page_offset", + io_mem.base & page_off_mask); + }); + }); + _irq_list.for_each([&] (Irq &) { + xml.node("irq", [&] () { + xml.attribute("id", irq_id++); }); + }); _property_list.for_each([&] (Property & p) { xml.node("property", [&] () { xml.attribute("name", p.name); xml.attribute("value", p.value); }); }); + _report_platform_specifics(xml, sc); }); } Genode::size_t Driver::Device::_cap_quota_required() { - Genode::size_t total = 0; + size_t total = 0; _io_mem_list.for_each([&] (Io_mem &) { - total += Genode::Io_mem_session::CAP_QUOTA; }); + total += Io_mem_session::CAP_QUOTA; }); return total; } Genode::size_t Driver::Device::_ram_quota_required() { - Genode::size_t total = 0; + size_t total = 0; _io_mem_list.for_each([&] (Io_mem & io_mem) { total += io_mem.size + 2*1024; }); return total; @@ -156,7 +172,6 @@ Driver::Device::Device(Name name) Driver::Device::~Device() { if (_session.valid()) { - Genode::error("Device to be destroyed, still obtained by session ", - _session); - } + error("Device to be destroyed, still obtained by session ", + _session); } } diff --git a/repos/os/src/drivers/platform/spec/arm/device.h b/repos/os/src/drivers/platform/spec/arm/device.h index 78b4b29e67..1cf5a633f7 100644 --- a/repos/os/src/drivers/platform/spec/arm/device.h +++ b/repos/os/src/drivers/platform/spec/arm/device.h @@ -24,35 +24,41 @@ #include namespace Driver { + using namespace Genode; + + class Env; class Device; struct Device_model; class Session_component; + struct Irq_update_policy; + struct Io_mem_update_policy; + struct Property_update_policy; } -class Driver::Device : public Genode::List_model::Element +class Driver::Device : private List_model::Element { public: - struct Io_mem : Genode::List_model::Element + struct Io_mem : List_model::Element { - Genode::addr_t base; - Genode::size_t size; - Genode::Io_mem_connection * io_mem { nullptr }; + addr_t base; + size_t size; + Io_mem_connection * io_mem { nullptr }; - Io_mem(Genode::addr_t base, Genode::size_t size) + Io_mem(addr_t base, size_t size) : base(base), size(size) {} }; - struct Irq : Genode::List_model::Element + struct Irq : List_model::Element { - unsigned number; - Genode::Irq_connection * irq { nullptr }; + unsigned number; + Irq_connection * irq { nullptr }; Irq(unsigned number) : number(number) {} }; - struct Property : Genode::List_model::Element + struct Property : List_model::Element { using Name = Genode::String<64>; using Value = Genode::String<64>; @@ -67,33 +73,37 @@ class Driver::Device : public Genode::List_model::Element using Name = Genode::String<64>; Device(Name name); - ~Device(); + virtual ~Device(); Name name() const; - bool acquire(Session_component &); - void release(Session_component &); + virtual bool acquire(Session_component &); + virtual void release(Session_component &); - Genode::Irq_session_capability irq(unsigned idx, - Session_component & session); - Genode::Io_mem_session_capability io_mem(unsigned idx, - Genode::Cache_attribute, - Session_component & session); + Irq_session_capability irq(unsigned idx, + Session_component & session); + Io_mem_session_capability io_mem(unsigned idx, Cache_attribute, + Session_component & session); - void report(Genode::Xml_generator &); + void report(Xml_generator &, Session_component &); - private: + protected: - Genode::size_t _cap_quota_required(); - Genode::size_t _ram_quota_required(); + virtual void _report_platform_specifics(Xml_generator &, + Session_component &) {} + + size_t _cap_quota_required(); + size_t _ram_quota_required(); friend class Driver::Device_model; + friend class List_model; + friend class List; - Name _name; - Platform::Session::Label _session {}; - Genode::List_model _io_mem_list {}; - Genode::List_model _irq_list {}; - Genode::List_model _property_list {}; + Name _name; + Platform::Session::Label _session {}; + List_model _io_mem_list {}; + List_model _irq_list {}; + List_model _property_list {}; /* * Noncopyable @@ -104,27 +114,25 @@ class Driver::Device : public Genode::List_model::Element class Driver::Device_model : - public Genode::List_model::Update_policy + public List_model::Update_policy { private: - Genode::Allocator & _alloc; - Genode::List_model _model {}; + Driver::Env & _env; + List_model _model {}; public: - void update(Genode::Xml_node const & node) { + void update(Xml_node const & node) { _model.update_from_xml(*this, node); } - Device_model(Genode::Allocator & alloc, - Genode::Xml_node const & node) - : _alloc(alloc) { update(node); } + Device_model(Driver::Env & env) + : _env(env) { } ~Device_model() { _model.destroy_all_elements(*this); } - template void for_each(FN const & fn) { _model.for_each(fn); } @@ -134,11 +142,106 @@ class Driver::Device_model : ***********************/ void destroy_element(Device & device); - Device & create_element(Genode::Xml_node node); - void update_element(Device & device, Genode::Xml_node node); - static bool element_matches_xml_node(Device const &, - Genode::Xml_node); - static bool node_is_element(Genode::Xml_node); + Device & create_element(Xml_node node); + void update_element(Device & device, Xml_node node); + static bool element_matches_xml_node(Device const & dev, + Genode::Xml_node n) { + return dev.name() == n.attribute_value("name", Device::Name()); } + + static bool node_is_element(Genode::Xml_node node) { + return node.has_type("device"); } +}; + + +struct Driver::Irq_update_policy : Genode::List_model::Update_policy +{ + Genode::Allocator & alloc; + + Irq_update_policy(Genode::Allocator & alloc) : alloc(alloc) {} + + void destroy_element(Element & irq) { + Genode::destroy(alloc, &irq); } + + Element & create_element(Genode::Xml_node node) + { + unsigned number = node.attribute_value("number", 0); + return *(new (alloc) Element(number)); + } + + void update_element(Element &, Genode::Xml_node) {} + + static bool element_matches_xml_node(Element const & irq, Genode::Xml_node node) + { + unsigned number = node.attribute_value("number", 0); + return number == irq.number; + } + + static bool node_is_element(Genode::Xml_node node) + { + return node.has_type("irq"); + } +}; + + +struct Driver::Io_mem_update_policy : Genode::List_model::Update_policy +{ + Genode::Allocator & alloc; + + Io_mem_update_policy(Genode::Allocator & alloc) : alloc(alloc) {} + + void destroy_element(Element & iomem) { + Genode::destroy(alloc, &iomem); } + + Element & create_element(Genode::Xml_node node) + { + Genode::addr_t base = node.attribute_value("address", 0); + Genode::size_t size = node.attribute_value("size", 0); + return *(new (alloc) Element(base, size)); + } + + void update_element(Element &, Genode::Xml_node) {} + + static bool element_matches_xml_node(Element const & iomem, Genode::Xml_node node) + { + Genode::addr_t base = node.attribute_value("address", 0); + Genode::size_t size = node.attribute_value("size", 0); + return (base == iomem.base) && (size == iomem.size); + } + + static bool node_is_element(Genode::Xml_node node) + { + return node.has_type("io_mem"); + } +}; + + +struct Driver::Property_update_policy : Genode::List_model::Update_policy +{ + Genode::Allocator & alloc; + + Property_update_policy(Genode::Allocator & alloc) : alloc(alloc) {} + + void destroy_element(Element & p) { + Genode::destroy(alloc, &p); } + + Element & create_element(Genode::Xml_node node) + { + return *(new (alloc) + Element(node.attribute_value("name", Element::Name()), + node.attribute_value("value", Element::Value()))); + } + + void update_element(Element &, Genode::Xml_node) {} + + static bool element_matches_xml_node(Element const & prop, Genode::Xml_node node) + { + Element::Name n = node.attribute_value("name", Element::Name()); + Element::Value v = node.attribute_value("value", Element::Value()); + return (n == prop.name) && (v == prop.value); + } + + static bool node_is_element(Genode::Xml_node node) { + return node.has_type("property"); } }; #endif /* _SRC__DRIVERS__PLATFORM__SPEC__ARM__DEVICE_H_ */ diff --git a/repos/os/src/drivers/platform/spec/arm/device_component.cc b/repos/os/src/drivers/platform/spec/arm/device_component.cc index 0c032af8eb..d626b96332 100644 --- a/repos/os/src/drivers/platform/spec/arm/device_component.cc +++ b/repos/os/src/drivers/platform/spec/arm/device_component.cc @@ -26,7 +26,7 @@ Driver::Session_component & Device_component::session() { return _session; } bool Driver::Device_component::acquire() { bool acquired = false; - _session.devices().for_each([&] (Driver::Device & device) { + _session.env().devices.for_each([&] (Driver::Device & device) { if (device.name() == _device) { acquired = device.acquire(_session); }}); return acquired; @@ -35,16 +35,16 @@ bool Driver::Device_component::acquire() void Driver::Device_component::release() { - _session.devices().for_each([&] (Driver::Device & device) { + _session.env().devices.for_each([&] (Driver::Device & device) { if (device.name() == _device) { device.release(_session); }}); } Genode::Io_mem_session_capability -Device_component::io_mem(unsigned idx, Genode::Cache_attribute attr) +Device_component::io_mem(unsigned idx, Cache_attribute attr) { - Genode::Io_mem_session_capability cap; - _session.devices().for_each([&] (Driver::Device & device) { + Io_mem_session_capability cap; + _session.env().devices.for_each([&] (Driver::Device & device) { if (device.name() == _device) { cap = device.io_mem(idx, attr, _session); }}); return cap; @@ -53,17 +53,17 @@ Device_component::io_mem(unsigned idx, Genode::Cache_attribute attr) Genode::Irq_session_capability Device_component::irq(unsigned idx) { - Genode::Irq_session_capability cap; - _session.devices().for_each([&] (Driver::Device & device) { + Irq_session_capability cap; + _session.env().devices.for_each([&] (Driver::Device & device) { if (device.name() == _device) { cap = device.irq(idx, _session); }}); return cap; } -void Driver::Device_component::report(Genode::Xml_generator & xml) +void Driver::Device_component::report(Xml_generator & xml) { - _session.devices().for_each([&] (Driver::Device & device) { - if (device.name() == _device) { device.report(xml); }}); + _session.env().devices.for_each([&] (Driver::Device & device) { + if (device.name() == _device) { device.report(xml, _session); }}); } diff --git a/repos/os/src/drivers/platform/spec/arm/device_component.h b/repos/os/src/drivers/platform/spec/arm/device_component.h index 41428e34d6..11fb980d9f 100644 --- a/repos/os/src/drivers/platform/spec/arm/device_component.h +++ b/repos/os/src/drivers/platform/spec/arm/device_component.h @@ -18,6 +18,7 @@ #include #include +#include #include namespace Driver { @@ -26,7 +27,7 @@ namespace Driver { } -class Driver::Device_component : public Genode::Rpc_object +class Driver::Device_component : public Rpc_object { public: @@ -40,17 +41,15 @@ class Driver::Device_component : public Genode::Rpc_object bool acquire(); void release(); - void report(Genode::Xml_generator&); + void report(Xml_generator&); /************************** ** Platform::Device API ** **************************/ - Genode::Irq_session_capability irq(unsigned) override; - - Genode::Io_mem_session_capability - io_mem(unsigned, Genode::Cache_attribute) override; + Irq_session_capability irq(unsigned) override; + Io_mem_session_capability io_mem(unsigned, Cache_attribute) override; private: @@ -59,7 +58,7 @@ class Driver::Device_component : public Genode::Rpc_object Session_component & _session; Driver::Device::Name const _device; Platform::Device_capability _cap {}; - Genode::List_element _list_elem { this }; + List_element _list_elem { this }; /* * Noncopyable diff --git a/repos/os/src/drivers/platform/spec/arm/device_model_policy.cc b/repos/os/src/drivers/platform/spec/arm/device_model_policy.cc index 112df74665..0321693b93 100644 --- a/repos/os/src/drivers/platform/spec/arm/device_model_policy.cc +++ b/repos/os/src/drivers/platform/spec/arm/device_model_policy.cc @@ -11,132 +11,37 @@ * under the terms of the GNU Affero General Public License version 3. */ +#include #include using Driver::Device_model; using Driver::Device; -struct Irq_update_policy : Genode::List_model::Update_policy -{ - Genode::Allocator & alloc; - - Irq_update_policy(Genode::Allocator & alloc) : alloc(alloc) {} - - void destroy_element(Element & irq) { - Genode::destroy(alloc, &irq); } - - Element & create_element(Genode::Xml_node node) - { - unsigned number = node.attribute_value("number", 0); - return *(new (alloc) Element(number)); - } - - void update_element(Element &, Genode::Xml_node) {} - - static bool element_matches_xml_node(Element const & irq, Genode::Xml_node node) - { - unsigned number = node.attribute_value("number", 0); - return number == irq.number; - } - - static bool node_is_element(Genode::Xml_node node) - { - using Name = Genode::String<16>; - return node.has_type("resource") && - (node.attribute_value("name", Name()) == "IRQ"); - } -}; - - -struct Io_mem_update_policy : Genode::List_model::Update_policy -{ - Genode::Allocator & alloc; - - Io_mem_update_policy(Genode::Allocator & alloc) : alloc(alloc) {} - - void destroy_element(Element & iomem) { - Genode::destroy(alloc, &iomem); } - - Element & create_element(Genode::Xml_node node) - { - Genode::addr_t base = node.attribute_value("address", 0); - Genode::size_t size = node.attribute_value("size", 0); - return *(new (alloc) Element(base, size)); - } - - void update_element(Element &, Genode::Xml_node) {} - - static bool element_matches_xml_node(Element const & iomem, Genode::Xml_node node) - { - Genode::addr_t base = node.attribute_value("address", 0); - Genode::size_t size = node.attribute_value("size", 0); - return (base == iomem.base) && (size == iomem.size); - } - - static bool node_is_element(Genode::Xml_node node) - { - bool iomem = node.attribute_value("name", Genode::String<16>()) - == "IO_MEM"; - return node.has_type("resource") && iomem; - } -}; - - -struct Property_update_policy : Genode::List_model::Update_policy -{ - Genode::Allocator & alloc; - - Property_update_policy(Genode::Allocator & alloc) : alloc(alloc) {} - - void destroy_element(Element & p) { - Genode::destroy(alloc, &p); } - - Element & create_element(Genode::Xml_node node) - { - return *(new (alloc) - Element(node.attribute_value("name", Element::Name()), - node.attribute_value("value", Element::Value()))); - } - - void update_element(Element &, Genode::Xml_node) {} - - static bool element_matches_xml_node(Element const & prop, Genode::Xml_node node) - { - Element::Name n = node.attribute_value("name", Element::Name()); - Element::Value v = node.attribute_value("value", Element::Value()); - return (n == prop.name) && (v == prop.value); - } - - static bool node_is_element(Genode::Xml_node node) { - return node.has_type("property"); } -}; - - void Device_model::destroy_element(Device & device) { { - Irq_update_policy policy(_alloc); + Irq_update_policy policy(_env.heap); device._irq_list.destroy_all_elements(policy); } { - Io_mem_update_policy policy(_alloc); + Io_mem_update_policy policy(_env.heap); device._io_mem_list.destroy_all_elements(policy); } { - Property_update_policy policy(_alloc); + Property_update_policy policy(_env.heap); device._property_list.destroy_all_elements(policy); } - Genode::destroy(_alloc, &device); + Genode::destroy(_env.heap, &device); } Device & Device_model::create_element(Genode::Xml_node node) { Device::Name name = node.attribute_value("name", Device::Name()); - return *(new (_alloc) Device(name)); + return *(new (_env.heap) Device(name)); } @@ -144,26 +49,17 @@ void Device_model::update_element(Device & device, Genode::Xml_node node) { { - Irq_update_policy policy(_alloc); + Irq_update_policy policy(_env.heap); device._irq_list.update_from_xml(policy, node); } { - Io_mem_update_policy policy(_alloc); + Io_mem_update_policy policy(_env.heap); device._io_mem_list.update_from_xml(policy, node); } { - Property_update_policy policy(_alloc); + Property_update_policy policy(_env.heap); device._property_list.update_from_xml(policy, node); } } - - -bool Device_model::element_matches_xml_node(Device const & dev, - Genode::Xml_node n) { - return dev.name() == n.attribute_value("name", Device::Name()); } - - -bool Device_model::node_is_element(Genode::Xml_node node) { - return node.has_type("device"); } diff --git a/repos/os/src/drivers/platform/spec/arm/env.h b/repos/os/src/drivers/platform/spec/arm/env.h new file mode 100644 index 0000000000..95e53abaec --- /dev/null +++ b/repos/os/src/drivers/platform/spec/arm/env.h @@ -0,0 +1,41 @@ +/* + * \brief Platform driver for ARM + * \author Stefan Kalkowski + * \date 2020-04-12 + */ + +/* + * Copyright (C) 2020 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. + */ + +#ifndef _SRC__DRIVERS__PLATFORM__SPEC__ARM__ENV_H_ +#define _SRC__DRIVERS__PLATFORM__SPEC__ARM__ENV_H_ + +#include +#include +#include + +#include + +namespace Driver { + using namespace Genode; + + struct Env; +}; + + +struct Driver::Env +{ + Genode::Env & env; + Heap heap { env.ram(), env.rm() }; + Sliced_heap sliced_heap { env.ram(), env.rm() }; + Attached_rom_dataspace config { env, "config" }; + Device_model devices { *this }; + + Env(Genode::Env &env) : env(env) {} +}; + +#endif /* _SRC__DRIVERS__PLATFORM__SPEC__ARM__ENV_H_ */ diff --git a/repos/os/src/drivers/platform/spec/arm/main.cc b/repos/os/src/drivers/platform/spec/arm/main.cc index 304f74c072..6a04c2885b 100644 --- a/repos/os/src/drivers/platform/spec/arm/main.cc +++ b/repos/os/src/drivers/platform/spec/arm/main.cc @@ -12,9 +12,7 @@ */ #include -#include -#include - +#include #include namespace Driver { struct Main; }; @@ -23,29 +21,25 @@ struct Driver::Main { void update_config(); - Genode::Env & env; - Genode::Heap heap { env.ram(), env.rm() }; - Genode::Sliced_heap sliced_heap { env.ram(), env.rm() }; - Genode::Attached_rom_dataspace config { env, "config" }; - Genode::Signal_handler
config_handler { env.ep(), *this, - &Main::update_config }; - Driver::Device_model devices { heap, config.xml() }; - Driver::Root root { env, sliced_heap, - config, devices }; + Driver::Env env; + Signal_handler
config_handler { env.env.ep(), *this, + &Main::update_config }; + Driver::Root root { env }; - Main(Genode::Env &env) - : env(env) + Main(Genode::Env & e) + : env(e) { - config.sigh(config_handler); - env.parent().announce(env.ep().manage(root)); + env.devices.update(env.config.xml()); + env.config.sigh(config_handler); + env.env.parent().announce(env.env.ep().manage(root)); } }; void Driver::Main::update_config() { - config.update(); - devices.update(config.xml()); + env.config.update(); + env.devices.update(env.config.xml()); root.update_policy(); } diff --git a/repos/os/src/drivers/platform/spec/arm/root.cc b/repos/os/src/drivers/platform/spec/arm/root.cc index bd28de6d29..770f4f7ac8 100644 --- a/repos/os/src/drivers/platform/spec/arm/root.cc +++ b/repos/os/src/drivers/platform/spec/arm/root.cc @@ -21,9 +21,9 @@ void Driver::Root::update_policy() unsigned device_count = 0; try { - Genode::Session_policy const policy { sc._label, _config.xml() }; + Session_policy const policy { sc._label, _env.config.xml() }; - policy.for_each_sub_node("device", [&] (Genode::Xml_node node) { + policy.for_each_sub_node("device", [&] (Xml_node node) { device_count++; if (!sc.has_device(node.attribute_value("name", Device::Name()))) { @@ -32,10 +32,10 @@ void Driver::Root::update_policy() if (device_count != sc.devices_count()) { policy_changed = true; } } - catch (Genode::Session_policy::No_policy_defined) { + catch (Session_policy::No_policy_defined) { policy_changed = true; - Genode::error("No matching policy for '", sc._label.string(), - "' anymore, will close the session!"); + error("No matching policy for '", sc._label.string(), + "' anymore, will close the session!"); } if (policy_changed) { close(sc.cap()); } @@ -45,25 +45,22 @@ void Driver::Root::update_policy() Driver::Session_component * Driver::Root::_create_session(const char *args) { - using namespace Genode; - Session_component * sc = nullptr; try { sc = new (md_alloc()) Session_component(_env, - _devices, _sessions, session_label_from_args(args), session_resources_from_args(args), session_diag_from_args(args)); - Session_policy const policy { sc->_label, _config.xml() }; + Session_policy const policy { sc->_label, _env.config.xml() }; policy.for_each_sub_node("device", [&] (Xml_node node) { sc->add(node.attribute_value("name", Driver::Device::Name())); }); } catch (Session_policy::No_policy_defined) { if (sc) { Genode::destroy(md_alloc(), sc); } error("Invalid session request, no matching policy for ", - "'", Genode::label_from_args(args).string(), "'"); + "'", label_from_args(args).string(), "'"); throw Service_denied(); } catch (...) { if (sc) { Genode::destroy(md_alloc(), sc); } @@ -76,14 +73,11 @@ Driver::Session_component * Driver::Root::_create_session(const char *args) void Driver::Root::_upgrade_session(Session_component * sc, const char * args) { - sc->upgrade(Genode::ram_quota_from_args(args)); - sc->upgrade(Genode::cap_quota_from_args(args)); + sc->upgrade(ram_quota_from_args(args)); + sc->upgrade(cap_quota_from_args(args)); } -Driver::Root::Root(Genode::Env & env, - Genode::Allocator & alloc, - Genode::Attached_rom_dataspace & config, - Driver::Device_model & devices) -: Genode::Root_component(env.ep(), alloc), - _env(env), _config(config), _devices(devices) { } +Driver::Root::Root(Driver::Env & env) +: Root_component(env.env.ep(), env.sliced_heap), + _env(env) { } diff --git a/repos/os/src/drivers/platform/spec/arm/root.h b/repos/os/src/drivers/platform/spec/arm/root.h index e084cb7a8e..56644ddeb2 100644 --- a/repos/os/src/drivers/platform/spec/arm/root.h +++ b/repos/os/src/drivers/platform/spec/arm/root.h @@ -23,14 +23,11 @@ namespace Driver { class Root; } -class Driver::Root : public Genode::Root_component +class Driver::Root : public Root_component { public: - Root(Genode::Env & env, - Genode::Allocator & alloc, - Genode::Attached_rom_dataspace & config, - Device_model & devices); + Root(Driver::Env & env); void update_policy(); @@ -40,10 +37,8 @@ class Driver::Root : public Genode::Root_component void _upgrade_session(Session_component *, const char *) override; - Genode::Env & _env; - Genode::Attached_rom_dataspace & _config; - Driver::Device_model & _devices; - Genode::Registry _sessions {}; + Driver::Env & _env; + Registry _sessions {}; }; #endif /* _SRC__DRIVERS__PLATFORM__SPEC__ARM__ROOT_H_ */ diff --git a/repos/os/src/drivers/platform/spec/arm/session_component.cc b/repos/os/src/drivers/platform/spec/arm/session_component.cc index cfb47be13b..26fa75b2df 100644 --- a/repos/os/src/drivers/platform/spec/arm/session_component.cc +++ b/repos/os/src/drivers/platform/spec/arm/session_component.cc @@ -18,7 +18,7 @@ using Driver::Session_component; -void Session_component::produce_xml(Genode::Xml_generator &xml) +void Session_component::produce_xml(Xml_generator &xml) { for (Device_list_element * e = _device_list.first(); e; e = e->next()) { e->object()->report(xml); } @@ -28,10 +28,7 @@ void Session_component::produce_xml(Genode::Xml_generator &xml) Genode::Heap & Session_component::heap() { return _md_alloc; } -Genode::Env & Session_component::env() { return _env; } - - -Driver::Device_model & Session_component::devices() { return _device_model; } +Driver::Env & Session_component::env() { return _env; } void Session_component::add(Device::Name const & device) @@ -67,6 +64,12 @@ unsigned Session_component::devices_count() const } +void Session_component::update_devices_rom() +{ + _rom_session.trigger_update(); +} + + Genode::Rom_session_capability Session_component::devices_rom() { return _rom_session.cap(); } @@ -78,15 +81,15 @@ Session_component::acquire_device(Platform::Session::String const &name) if (e->object()->device() != name.string()) { continue; } if (!e->object()->acquire()) { - Genode::error("Device ", e->object()->device(), + error("Device ", e->object()->device(), " already acquired!"); break; } /* account one device capability needed */ - _cap_quota_guard().replenish(Genode::Cap_quota{1}); + _cap_quota_guard().replenish(Cap_quota{1}); - return _env.ep().rpc_ep().manage(e->object()); + return _env.env.ep().rpc_ep().manage(e->object()); } return Platform::Device_capability(); @@ -95,28 +98,27 @@ Session_component::acquire_device(Platform::Session::String const &name) void Session_component::release_device(Platform::Device_capability device_cap) { - _env.ep().rpc_ep().apply(device_cap, [&] (Device_component * dc) { - _env.ep().rpc_ep().dissolve(dc); - _cap_quota_guard().replenish(Genode::Cap_quota{1}); + _env.env.ep().rpc_ep().apply(device_cap, [&] (Device_component * dc) { + _env.env.ep().rpc_ep().dissolve(dc); + _cap_quota_guard().replenish(Cap_quota{1}); dc->release(); }); } Genode::Ram_dataspace_capability -Session_component::alloc_dma_buffer(Genode::size_t const size) +Session_component::alloc_dma_buffer(size_t const size) { - Genode::Ram_dataspace_capability ram_cap = - _env_ram.alloc(size, Genode::UNCACHED); + Ram_dataspace_capability ram_cap = _env_ram.alloc(size, UNCACHED); if (!ram_cap.valid()) return ram_cap; try { _buffer_list.insert(new (_md_alloc) Dma_buffer(ram_cap)); - } catch (Genode::Out_of_ram) { + } catch (Out_of_ram) { _env_ram.free(ram_cap); throw; - } catch (Genode::Out_of_caps) { + } catch (Out_of_caps) { _env_ram.free(ram_cap); throw; } @@ -125,7 +127,7 @@ Session_component::alloc_dma_buffer(Genode::size_t const size) } -void Session_component::free_dma_buffer(Genode::Ram_dataspace_capability ram_cap) +void Session_component::free_dma_buffer(Ram_dataspace_capability ram_cap) { if (!ram_cap.valid()) { return; } @@ -149,7 +151,7 @@ Genode::addr_t Session_component::bus_addr_dma_buffer(Ram_dataspace_capability r if (buf->cap.local_name() != ram_cap.local_name()) continue; - Genode::Dataspace_client dsc(buf->cap); + Dataspace_client dsc(buf->cap); return dsc.phys_addr(); } @@ -157,18 +159,15 @@ Genode::addr_t Session_component::bus_addr_dma_buffer(Ram_dataspace_capability r } -Session_component::Session_component(Genode::Env & env, - Device_model & devices, - Registry & registry, +Session_component::Session_component(Driver::Env & env, + Session_registry & registry, Label const & label, Resources const & resources, Diag const & diag) -: Genode::Session_object(env.ep(), resources, - label, diag), - Registry::Element(registry, *this), - Genode::Dynamic_rom_session::Xml_producer("devices"), - _env(env), - _device_model(devices) +: Session_object(env.env.ep(), resources, label, diag), + Session_registry::Element(registry, *this), + Dynamic_rom_session::Xml_producer("devices"), + _env(env) { /* * FIXME: As the ROM session does not propagate Out_of_* @@ -179,8 +178,8 @@ Session_component::Session_component(Genode::Env & env, * we account the costs here until the ROM session interface * changes. */ - _cap_quota_guard().withdraw(Genode::Cap_quota{1}); - _ram_quota_guard().withdraw(Genode::Ram_quota{5*1024}); + _cap_quota_guard().withdraw(Cap_quota{1}); + _ram_quota_guard().withdraw(Ram_quota{5*1024}); } @@ -193,6 +192,6 @@ Session_component::~Session_component() } /* replenish quota for rom sessions, see constructor for explanation */ - _cap_quota_guard().replenish(Genode::Cap_quota{1}); - _ram_quota_guard().replenish(Genode::Ram_quota{5*1024}); + _cap_quota_guard().replenish(Cap_quota{1}); + _ram_quota_guard().replenish(Ram_quota{5*1024}); } diff --git a/repos/os/src/drivers/platform/spec/arm/session_component.h b/repos/os/src/drivers/platform/spec/arm/session_component.h index 3d9f0d3c78..eeafc205ef 100644 --- a/repos/os/src/drivers/platform/spec/arm/session_component.h +++ b/repos/os/src/drivers/platform/spec/arm/session_component.h @@ -32,79 +32,71 @@ namespace Driver { class Driver::Session_component : - public Genode::Session_object, - private Genode::Registry::Element, - private Genode::Dynamic_rom_session::Xml_producer + public Session_object, + private Registry::Element, + private Dynamic_rom_session::Xml_producer { public: - using Registry = Genode::Registry; + using Session_registry = Registry; - Session_component(Genode::Env & env, - Device_model & devices, - Registry & registry, - Label const & label, - Resources const & resources, - Diag const & diag); + Session_component(Driver::Env & env, + Session_registry & registry, + Label const & label, + Resources const & resources, + Diag const & diag); ~Session_component(); - Genode::Heap & heap(); - Genode::Env & env(); - Device_model & devices(); + Heap & heap(); + Driver::Env & env(); void add(Device::Name const &); bool has_device(Device::Name const &) const; unsigned devices_count() const; + void update_devices_rom(); - Genode::Ram_quota_guard &ram_quota_guard() { - return _ram_quota_guard(); } - - Genode::Cap_quota_guard &cap_quota_guard() { - return _cap_quota_guard(); } + Ram_quota_guard & ram_quota_guard() { return _ram_quota_guard(); } + Cap_quota_guard & cap_quota_guard() { return _cap_quota_guard(); } /************************** ** Platform Session API ** **************************/ - using Rom_session_capability = Genode::Rom_session_capability; - using Device_capability = Platform::Device_capability; - using Ram_dataspace_capability = Genode::Ram_dataspace_capability; - using String = Platform::Session::String; - using size_t = Genode::size_t; + using Device_capability = Platform::Device_capability; + using String = Platform::Session::String; Rom_session_capability devices_rom() override; Device_capability acquire_device(String const &) override; void release_device(Device_capability) override; Ram_dataspace_capability alloc_dma_buffer(size_t const) override; void free_dma_buffer(Ram_dataspace_capability ram_cap) override; - Genode::addr_t bus_addr_dma_buffer(Ram_dataspace_capability) override; + addr_t bus_addr_dma_buffer(Ram_dataspace_capability) override; private: friend class Root; - struct Dma_buffer : Genode::List::Element + struct Dma_buffer : List::Element { - Genode::Ram_dataspace_capability const cap; + Ram_dataspace_capability const cap; - Dma_buffer(Genode::Ram_dataspace_capability const cap) + Dma_buffer(Ram_dataspace_capability const cap) : cap(cap) {} }; - using Device_list_element = Genode::List_element; - using Device_list = Genode::List; + using Device_list_element = List_element; + using Device_list = List; - Genode::Env & _env; - Genode::Constrained_ram_allocator _env_ram { _env.pd(), - _ram_quota_guard(), - _cap_quota_guard() }; - Genode::Heap _md_alloc { _env_ram, _env.rm() }; - Device_list _device_list { }; - Genode::List _buffer_list { }; - Genode::Dynamic_rom_session _rom_session { _env.ep(), _env.ram(), - _env.rm(), *this }; - Device_model & _device_model; + Driver::Env & _env; + Constrained_ram_allocator _env_ram { _env.env.pd(), + _ram_quota_guard(), + _cap_quota_guard() }; + Heap _md_alloc { _env_ram, _env.env.rm() }; + Device_list _device_list { }; + List _buffer_list { }; + Dynamic_rom_session _rom_session { _env.env.ep(), _env.env.ram(), + _env.env.rm(), *this }; /* * Noncopyable @@ -117,7 +109,7 @@ class Driver::Session_component : ** Dynamic_rom_session::Xml_producer API ** *******************************************/ - void produce_xml(Genode::Xml_generator &xml) override; + void produce_xml(Xml_generator &xml) override; }; #endif /* _SRC__DRIVERS__PLATFORM__SPEC__ARM__SESSION_COMPONENT_H_ */