foc: Odroid-X2 basic support

Fix #1597
This commit is contained in:
Alexy Gallardo Segura 2015-04-28 08:04:37 -04:00 committed by Norman Feske
parent c42e770384
commit c14fe7e6c7
19 changed files with 929 additions and 4 deletions

View File

@ -0,0 +1,94 @@
#
# Automatically generated file; DO NOT EDIT.
# Fiasco configuration
#
#
# Target configuration
#
# CONFIG_IA32 is not set
# CONFIG_AMD64 is not set
CONFIG_ARM=y
# CONFIG_PF_TEGRA is not set
# CONFIG_PF_REALVIEW is not set
# CONFIG_PF_BCM2835 is not set
# CONFIG_PF_IMX is not set
# CONFIG_PF_S3C2410 is not set
# CONFIG_PF_SA1100 is not set
CONFIG_PF_EXYNOS=y
# CONFIG_PF_INTEGRATOR is not set
# CONFIG_PF_KIRKWOOD is not set
# CONFIG_PF_OMAP is not set
# CONFIG_PF_XSCALE is not set
CONFIG_BSP_NAME="exynos"
CONFIG_PF_EXYNOS4=y
CONFIG_PF_EXYNOS_PKG_IDS=""
# CONFIG_PF_EXYNOS4_4210 is not set
CONFIG_PF_EXYNOS4_4412=y
# CONFIG_PF_EXYNOS5_5250 is not set
CONFIG_PF_EXYNOS_UART_NR=1
CONFIG_PF_EXYNOS_TIMER_MCT=y
# CONFIG_PF_EXYNOS_TIMER_MP is not set
# CONFIG_PF_EXYNOS_TIMER_PWM is not set
CONFIG_PF_EXYNOS_EXTGIC=y
CONFIG_ABI_VF=y
CONFIG_PF_ARM_MP_CAPABLE=y
CONFIG_CAN_ARM_CPU_CORTEX_A9=y
CONFIG_CAN_ARM_CACHE_L2CXX0=y
CONFIG_ARM_CORTEX_A9=y
# CONFIG_ARM_ALIGNMENT_CHECK is not set
# CONFIG_ARM_EM_STD is not set
CONFIG_ARM_EM_NS=y
# CONFIG_ARM_EM_TZ is not set
CONFIG_ARM_SECMONIF_MC=y
# CONFIG_ARM_ENABLE_SWP is not set
CONFIG_ARM_CACHE_L2CXX0=y
CONFIG_FPU=y
# CONFIG_ARM_CPU_ERRATA is not set
#
# Kernel options
#
CONFIG_MP=y
CONFIG_MP_MAX_CPUS=4
CONFIG_CONTEXT_4K=y
# CONFIG_FINE_GRAINED_CPUTIME is not set
CONFIG_SCHED_FIXED_PRIO=y
CONFIG_VIRT_OBJ_SPACE=y
#
# Debugging
#
CONFIG_INLINE=y
# CONFIG_NDEBUG is not set
CONFIG_NO_FRAME_PTR=y
# CONFIG_STACK_DEPTH is not set
# CONFIG_LIST_ALLOC_SANITY is not set
CONFIG_SERIAL=y
CONFIG_JDB=y
# CONFIG_JDB_LOGGING is not set
# CONFIG_JDB_DISASM is not set
# CONFIG_JDB_GZIP is not set
# CONFIG_VMEM_ALLOC_TEST is not set
# CONFIG_DEBUG_KERNEL_PAGE_FAULTS is not set
# CONFIG_WARN_NONE is not set
CONFIG_WARN_WARNING=y
# CONFIG_WARN_ANY is not set
#
# Compiling
#
CONFIG_CC="gcc"
CONFIG_CXX="g++"
CONFIG_HOST_CC="gcc"
CONFIG_HOST_CXX="g++"
# CONFIG_MAINTAINER_MODE is not set
CONFIG_LABEL=""
# CONFIG_EXPERIMENTAL is not set
CONFIG_PERF_CNT=y
CONFIG_BIT32=y
CONFIG_ARM_V7=y
CONFIG_ARM_V6PLUS=y
CONFIG_WARN_LEVEL=1
CONFIG_XARCH="arm"
CONFIG_ABI="vf"

View File

@ -0,0 +1,70 @@
#
# Automatically generated file; DO NOT EDIT.
# L4Re Configuration
#
# CONFIG_BUILD_ARCH_x86 is not set
# CONFIG_BUILD_ARCH_amd64 is not set
CONFIG_BUILD_ARCH_arm=y
# CONFIG_BUILD_ARCH_ppc32 is not set
# CONFIG_BUILD_ARCH_sparc is not set
CONFIG_BUILD_ARCH="arm"
CONFIG_BUILD_ABI_l4f=y
CONFIG_BUILD_ABI="l4f"
CONFIG_CPU="armv7a"
# CONFIG_CPU_ARM_ARMV4 is not set
# CONFIG_CPU_ARM_ARMV4T is not set
# CONFIG_CPU_ARM_ARMV5 is not set
# CONFIG_CPU_ARM_ARMV5T is not set
# CONFIG_CPU_ARM_ARMV5TE is not set
# CONFIG_CPU_ARM_ARMV6 is not set
# CONFIG_CPU_ARM_ARMV6T2 is not set
# CONFIG_CPU_ARM_ARMV6ZK is not set
CONFIG_CPU_ARM_ARMV7A=y
# CONFIG_CPU_ARM_ARMV7R is not set
CONFIG_CPU_ARMV6KPLUS=y
CONFIG_CPU_ARMV6PLUS=y
CONFIG_PLATFORM_TYPE_exynos4=y
# CONFIG_PLATFORM_TYPE_imx6 is not set
# CONFIG_PLATFORM_TYPE_imx35 is not set
# CONFIG_PLATFORM_TYPE_rv_pbx is not set
# CONFIG_PLATFORM_TYPE_exynos5 is not set
# CONFIG_PLATFORM_TYPE_rv is not set
# CONFIG_PLATFORM_TYPE_kirkwood is not set
# CONFIG_PLATFORM_TYPE_pandaboard is not set
# CONFIG_PLATFORM_TYPE_tegra3 is not set
# CONFIG_PLATFORM_TYPE_tegra2 is not set
# CONFIG_PLATFORM_TYPE_omap3_am33xx is not set
# CONFIG_PLATFORM_TYPE_rpi_b is not set
# CONFIG_PLATFORM_TYPE_rv_vexpress_a15 is not set
# CONFIG_PLATFORM_TYPE_imx51 is not set
# CONFIG_PLATFORM_TYPE_omap3evm is not set
# CONFIG_PLATFORM_TYPE_beagleboard is not set
# CONFIG_PLATFORM_TYPE_imx21 is not set
# CONFIG_PLATFORM_TYPE_rv_vexpress is not set
# CONFIG_PLATFORM_TYPE_imx53 is not set
# CONFIG_PLATFORM_TYPE_rpi_a is not set
# CONFIG_PLATFORM_TYPE_integrator is not set
# CONFIG_PLATFORM_TYPE_custom is not set
CONFIG_PLATFORM_TYPE="exynos4"
# CONFIG_USE_DROPS_STDDIR is not set
# CONFIG_USE_DICE is not set
CONFIG_DROPS_STDDIR="/path/to/l4re"
CONFIG_DROPS_INSTDIR="/path/to/l4re"
CONFIG_BID_COLORED_PHASES=y
#
# Building
#
CONFIG_YACC="yacc"
CONFIG_LEX="flex"
CONFIG_CTAGS="ctags"
CONFIG_ETAGS="etags"
CONFIG_HAVE_LDSO=y
CONFIG_INT_CPP_NAME_SWITCH=y
CONFIG_INT_LD_NAME_SWITCH=y
# CONFIG_BID_STRIP_PROGS is not set
# CONFIG_BID_GCC_OMIT_FP is not set
# CONFIG_BID_GENERATE_MAPFILE is not set
# CONFIG_BID_BUILD_DOC is not set
# CONFIG_RELEASE_MODE is not set
CONFIG_MAKECONFS_ADD=""

View File

@ -0,0 +1,6 @@
#
# Configuration for L4 build system (for kernel-bindings, sigma0, bootstrap).
#
L4_CONFIG = $(call select_from_repositories,config/odroid_x2.user)
include $(REP_DIR)/lib/mk/arm/platform.inc

View File

@ -0,0 +1,4 @@
SPECS += foc_arm platform_odroid_x2
include $(call select_from_repositories,mk/spec-platform_odroid_x2.mk)
include $(call select_from_repositories,mk/spec-foc_arm.mk)

View File

@ -0,0 +1,4 @@
LD_TEXT_ADDR = 0x80100000
REQUIRES += foc_odroid_x2
include $(REP_DIR)/src/core/arm/target.inc

View File

@ -0,0 +1,5 @@
REQUIRES = platform_odroid_x2
FIASCO_DIR := $(call select_from_ports,foc)/src/kernel/foc/kernel/fiasco
KERNEL_CONFIG = $(REP_DIR)/config/odroid_x2.kernel
-include $(PRG_DIR)/../target.inc

View File

@ -0,0 +1,42 @@
/*
* \brief Driver base for Odroid-x2 board
* \author Alexy Gallardo Segura <alexy@uclv.cu>
* \author Humberto López León <humberto@uclv.cu>
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
* \date 2015-04-27
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__DRIVERS__BOARD_BASE_H_
#define _INCLUDE__DRIVERS__BOARD_BASE_H_
/* Genode includes */
#include <platform_exynos4/board_base.h>
namespace Genode { struct Board_base; }
/**
* Board driver base
*/
struct Genode::Board_base : Exynos4
{
enum
{
/* clock management unit */
CMU_MMIO_BASE = 0x10040000,
CMU_MMIO_SIZE = 0x18000,
/* power management unit */
PMU_MMIO_BASE = 0x10020000,
PMU_MMIO_SIZE = 0x5000,
};
};
#endif /* _INCLUDE__DRIVERS__BOARD_BASE_H_ */

View File

@ -0,0 +1,29 @@
/*
* \brief Board-driver base
* \author Alexy Gallardo Segura <alexy@uclv.cu>
* \author Humberto López León <humberto@uclv.cu>
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
* \date 2015-04-28
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _EXYNOS4__BOARD_BASE_H_
#define _EXYNOS4__BOARD_BASE_H_
namespace Genode { struct Exynos4; }
/**
* Board-driver base
*/
struct Genode::Exynos4
{
};
#endif /* _EXYNOS4__BOARD_BASE_H_ */

View File

@ -0,0 +1,17 @@
#
# \brief Build-system configurations for Odrod-x2
# \author Alexy Gallardo Segura <alexy@uclv.cu>
# \author Humberto López León <humberto@uclv.cu>
# \author Reinier Millo Sánchez <rmillo@uclv.cu>
# \date 2015-04-28
#
# denote specs that are fullfilled by this spec
SPECS += exynos4 cortex_a9
# add repository relative paths
REP_INC_DIR += include/platform/odroid_x2
REP_INC_DIR += include/platform/exynos4
# include implied specs
include $(call select_from_repositories,mk/spec-cortex_a9.mk)

View File

@ -10,6 +10,7 @@ if {
![have_spec foc_x86_64] &&
![have_spec foc_panda] &&
![have_spec foc_arndale] &&
![have_spec foc_odroid_x2] &&
![have_spec nova]
} {
puts "Platform is unsupported."

View File

@ -2,7 +2,11 @@ proc have_platform_drv {} {
if {[have_spec linux]} {
return 0
}
return [expr [have_spec platform_arndale] || [have_spec platform_imx53] || [have_spec platform_rpi] || [have_spec x86]]
return [expr [have_spec platform_arndale] \
|| [have_spec platform_imx53] \
|| [have_spec platform_rpi] \
|| [have_spec platform_odroid_x2] \
|| [have_spec x86]]
}
proc append_platform_drv_build_components {} {

View File

@ -0,0 +1,73 @@
/*
* \brief Regulator definitions for Exynos4412
* \author Stefan Kalkowski <stefan.kalkowski@genode-labs.com>
* \date 2013-06-13
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__PLATFORM__EXYNOS4412__REGULATOR__CONSTS_H_
#define _INCLUDE__PLATFORM__EXYNOS4412__REGULATOR__CONSTS_H_
#include <util/string.h>
namespace Regulator {
enum Regulator_id {
CLK_CPU,
CLK_USB20,
CLK_MMC0,
CLK_HDMI,
PWR_USB20,
PWR_HDMI,
MAX,
INVALID
};
struct Regulator_name {
Regulator_id id;
const char * name;
};
Regulator_name names[] = {
{ CLK_CPU, "clock-cpu" },
{ CLK_USB20, "clock-usb2.0" },
{ CLK_MMC0, "clock-mmc0" },
{ CLK_HDMI, "clock-hdmi" },
{ PWR_USB20, "power-usb2.0" },
{ PWR_HDMI, "power-hdmi"},
};
Regulator_id regulator_id_by_name(const char * name)
{
for (unsigned i = 0; i < sizeof(names)/sizeof(names[0]); i++)
if (Genode::strcmp(names[i].name, name) == 0)
return names[i].id;
return INVALID;
}
const char * regulator_name_by_id(Regulator_id id) {
return (id < sizeof(names)/sizeof(names[0])) ? names[id].name : 0; }
/***************************************
** Device specific level definitions **
***************************************/
enum Cpu_clock_freq {
CPU_FREQ_200 = 200000000,
CPU_FREQ_400 = 400000000,
CPU_FREQ_600 = 600000000,
CPU_FREQ_800 = 800000000,
CPU_FREQ_1000 = 1000000000,
CPU_FREQ_1200 = 1200000000,
CPU_FREQ_1400 = 1400000000,
};
}
#endif /* _INCLUDE__PLATFORM__EXYNOS4412__REGULATOR__CONSTS_H_ */

View File

@ -0,0 +1,284 @@
/*
* \brief Regulator driver for clock management unit of Exynos4412 SoC
* \author Alexy Gallardo Segura <alexy@uclv.cu>
* \author Humberto Lopez Leon <humberto@uclv.cu>
* \author Reinier Millo Sanchez <rmillo@uclv.cu>
* \date 2015-04-30
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _CMU_H_
#define _CMU_H_
#include <regulator/consts.h>
#include <regulator/driver.h>
#include <drivers/board_base.h>
#include <os/attached_mmio.h>
#include <base/printf.h>
using namespace Regulator;
class Cmu : public Regulator::Driver,
public Genode::Attached_mmio
{
private:
static const Genode::uint16_t m_values[]; /* M values for frequencies */
static const Genode::uint8_t p_values[]; /* P values for frequencies */
static const Genode::uint8_t s_values[]; /* S values for frequencies */
template <unsigned OFF>
struct Pll_lock : Register<OFF, 32>
{
struct Pll_locktime : Register<OFF, 32>::template Bitfield<0, 20> { };
static Genode::uint32_t max_lock_time(Genode::uint8_t pdiv) {
return pdiv * 250; };
};
template <unsigned OFF>
struct Pll_con0 : Register<OFF, 32>
{
struct S : Register<OFF, 32>::template Bitfield < 0, 3> { };
struct P : Register<OFF, 32>::template Bitfield < 8, 6> { };
struct M : Register<OFF, 32>::template Bitfield <16, 10> { };
struct Locked : Register<OFF, 32>::template Bitfield <29, 1> { };
struct Enable : Register<OFF, 32>::template Bitfield <31, 1> { };
};
/***********************
** CMU CPU registers **
***********************/
typedef Pll_lock<4000> Apll_lock;
typedef Pll_con0<0x4100> Apll_con0;
struct Clk_src_cpu : Register<0x4200, 32>
{
struct Mux_core_sel : Bitfield<16, 1>
{
enum { MOUT_APLL, SCLK_MPLL};
};
};
struct Clk_mux_stat_cpu : Register<0x4400, 32>
{
struct Core_sel : Bitfield<16, 3>
{
enum { MOUT_APLL = 0b1, SCLK_MPLL = 0b10 };
};
};
struct Clk_div_cpu0 : Register<0x4500, 32>
{
/* Cpu0 divider values for frequencies 200 - 1400 */
static const Genode::uint32_t values[];
};
struct Clk_div_cpu1 : Register<0x4504, 32>
{
/* Divider for cpu1 doesn't change */
enum { FIX_VALUE = 32 };
};
struct Clk_div_stat_cpu0 : Register<0x4600, 32>
{
struct Div_core : Bitfield< 0, 1> {};
struct Div_corem0 : Bitfield< 4, 1> {};
struct Div_corem1 : Bitfield< 8, 1> {};
struct Div_pheriph : Bitfield<12, 1> {};
struct Div_atb : Bitfield<16, 1> {};
struct Div_pclk_dbg : Bitfield<20, 1> {};
struct Div_apll : Bitfield<24, 1> {};
struct Div_core2 : Bitfield<28, 1> {};
static bool in_progress(access_t stat_word)
{
return stat_word & (Div_core::bits(1) |
Div_corem0::bits(1) |
Div_corem1::bits(1) |
Div_pheriph::bits(1) |
Div_atb::bits(1) |
Div_pclk_dbg::bits(1) |
Div_apll::bits(1) |
Div_core2::bits(1));
}
};
struct Clk_div_stat_cpu1 : Register<0x4604, 32>
{
struct Div_copy : Bitfield<0, 1> { };
struct Div_hpm : Bitfield<4, 1> { };
static bool in_progress(access_t stat_word)
{
return stat_word & (Div_copy::bits(1) |
Div_hpm::bits(1));
}
};
/************************
** CMU CORE registers **
************************/
typedef Pll_lock<0x0008> Mpll_lock;
typedef Pll_con0<0x0108> Mpll_con0;
struct Clk_src_dmc : Register<0x4200, 32>
{
struct Mux_mpll_sel : Bitfield<12, 1> { enum { XXTI, MPLL_FOUT_RGT }; };
};
struct Clk_gate_ip_dmc : Register<0x0900, 32> { };
struct Clk_gate_ip_isp0 : Register<0x8800, 32> { };
struct Clk_gate_ip_isp1 : Register<0x8804, 32> { };
/*******************
** CPU functions **
*******************/
Cpu_clock_freq _cpu_freq;
void _cpu_clk_freq(unsigned long level)
{
PINF("Setting CPU frequency %lu\n",level);
unsigned freq;
switch (level) {
case CPU_FREQ_200:
freq = 0;
break;
case CPU_FREQ_400:
freq = 1;
break;
case CPU_FREQ_600:
freq = 2;
break;
case CPU_FREQ_800:
freq = 3;
break;
case CPU_FREQ_1000:
freq = 4;
break;
case CPU_FREQ_1200:
freq = 5;
break;
case CPU_FREQ_1400:
freq = 6;
break;
default:
PWRN("Unsupported CPU frequency level %ld", level);
PWRN("Supported values are 200, 400, 600, 800, 1000, 1200, 14000 MHz");
PWRN("and 1, 1.2, 1.4, 1.6, 1.7 GHz");
return;
};
/**
* change clock divider values
*/
/* cpu0 divider */
write<Clk_div_cpu0>(Clk_div_cpu0::values[freq]);
while (Clk_div_stat_cpu0::in_progress(read<Clk_div_stat_cpu0>())) ;
/* cpu1 divider */
write<Clk_div_cpu1>(Clk_div_cpu1::FIX_VALUE);
while (Clk_div_stat_cpu1::in_progress(read<Clk_div_stat_cpu1>())) ;
/**
* change APLL frequency
*/
/* change reference clock to MPLL */
write<Clk_src_cpu::Mux_core_sel>(Clk_src_cpu::Mux_core_sel::SCLK_MPLL);
while (read<Clk_mux_stat_cpu::Core_sel>()
!= Clk_mux_stat_cpu::Core_sel::SCLK_MPLL) ;
/* set lock time */
unsigned pdiv = p_values[freq];
write<Apll_lock::Pll_locktime>(Apll_lock::max_lock_time(pdiv));
/* change P, M, S values of APLL */
write<Apll_con0::P>(p_values[freq]);
write<Apll_con0::M>(m_values[freq]);
write<Apll_con0::S>(s_values[freq]);
while (!read<Apll_con0::Locked>()) ;
/* change reference clock back to APLL */
write<Clk_src_cpu::Mux_core_sel>(Clk_src_cpu::Mux_core_sel::MOUT_APLL);
while (read<Clk_mux_stat_cpu::Core_sel>()
!= Clk_mux_stat_cpu::Core_sel::MOUT_APLL) ;
_cpu_freq = static_cast<Cpu_clock_freq>(level);
}
public:
/**
* Constructor
*/
Cmu()
: Genode::Attached_mmio(Genode::Board_base::CMU_MMIO_BASE,
Genode::Board_base::CMU_MMIO_SIZE),
_cpu_freq(CPU_FREQ_1400)
{
/**
* Set default CPU frequency
*/
_cpu_clk_freq(_cpu_freq);
}
/********************************
** Regulator driver interface **
********************************/
void level(Regulator_id id, unsigned long level)
{
switch (id) {
case CLK_CPU:
_cpu_clk_freq(level);
break;
default:
PWRN("Unsupported for %s", names[id].name);
}
}
unsigned long level(Regulator_id id)
{
switch (id) {
case CLK_CPU:
return _cpu_freq;
default:
PWRN("Unsupported for %s", names[id].name);
}
return 0;
}
void state(Regulator_id id, bool enable)
{
}
bool state(Regulator_id id)
{
return true;
}
};
const Genode::uint8_t Cmu::s_values[] = { 2, 1, 1, 0, 0, 0, 0, 0, 0 };
const Genode::uint16_t Cmu::m_values[] = { 100, 100, 200, 100, 125,
150, 175, 200, 425 };
const Genode::uint8_t Cmu::p_values[] = { 3, 3, 4, 3, 3, 3, 3, 3, 6 };
const Genode::uint32_t Cmu::Clk_div_cpu0::values[] = { 0x1117710, 0x1127710, 0x1137710,
0x2147710, 0x2147710, 0x3157720,
0x4167720};
#endif /* _CMU_H_ */

View File

@ -0,0 +1,59 @@
/*
* \brief Driver for Odroid-x2 specific platform devices (clocks, power, etc.)
* \author Alexy Gallardo Segura <alexy@uclv.cu>
* \author Humberto Lopez Leon <humberto@uclv.cu>
* \author Reinier Millo Sanchez <rmillo@uclv.cu>
* \date 2015-04-30
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
#include <base/sleep.h>
#include <cap_session/connection.h>
#include <regulator/component.h>
#include <regulator/consts.h>
#include <cmu.h>
#include <pmu.h>
struct Driver_factory: Regulator::Driver_factory
{
Cmu _cmu;
Regulator::Driver &create(Regulator::Regulator_id id)
{
switch (id) {
case Regulator::CLK_CPU:
return _cmu;
default:
throw Root::Invalid_args(); /* invalid regulator */
};
}
void destroy(Regulator::Driver &driver) {
}
};
int main(int, char **)
{
using namespace Genode;
PINF("--- Odroid-x2 platform driver ---\n");
static Cap_connection cap;
static Rpc_entrypoint ep(&cap, 4096, "odroid_x2_plat_ep");
static ::Driver_factory driver_factory;
static Regulator::Root reg_root(&ep, env()->heap(), driver_factory);
env()->parent()->announce(ep.manage(&reg_root));
sleep_forever();
return 0;
}

View File

@ -0,0 +1,218 @@
/*
* \brief Regulator driver for power management unit of Exynos4412 SoC
* \author Alexy Gallardo Segura <alexy@uclv.cu>
* \author Humberto Lopez Leon <humberto@uclv.cu>
* \author Reinier Millo Sanchez <rmillo@uclv.cu>
* \date 2015-04-30
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _PMU_H_
#define _PMU_H_
#include <regulator/consts.h>
#include <regulator/driver.h>
#include <drivers/board_base.h>
#include <os/attached_mmio.h>
using namespace Regulator;
class Pmu : public Regulator::Driver,
public Genode::Attached_mmio
{
private:
template <unsigned OFFSET>
struct Control : Register <OFFSET, 32>
{
struct Enable : Register<OFFSET, 32>::template Bitfield<0, 1> { };
};
template <unsigned OFFSET>
struct Configuration : Register <OFFSET, 32>
{
struct Local_pwr_cfg : Register<OFFSET, 32>::template Bitfield<0, 3> { };
};
template <unsigned OFFSET>
struct Status : Register <OFFSET, 32>
{
struct Stat : Register<OFFSET, 32>::template Bitfield<0, 3> { };
};
template <unsigned OFFSET>
struct Sysclk_configuration : Register <OFFSET, 32>
{
struct Local_pwr_cfg : Register<OFFSET, 32>::template Bitfield<0, 1> { };
};
template <unsigned OFFSET>
struct Sysclk_status : Register <OFFSET, 32>
{
struct Stat : Register<OFFSET, 32>::template Bitfield<0, 1> { };
};
struct Hdmi_phy_control : Register<0x700, 32>
{
struct Enable : Bitfield<0, 1> { };
struct Div_ratio : Bitfield<16, 10> { };
};
typedef Control<0x704> Usbdrd_phy_control;
typedef Control<0x708> Usbhost_phy_control;
typedef Control<0x70c> Efnand_phy_control;
typedef Control<0x718> Adc_phy_control;
typedef Control<0x71c> Mtcadc_phy_control;
typedef Control<0x720> Dptx_phy_control;
typedef Control<0x724> Sata_phy_control;
typedef Sysclk_configuration<0x2a40> Vpll_sysclk_configuration;
typedef Sysclk_status<0x2a44> Vpll_sysclk_status;
typedef Sysclk_configuration<0x2a60> Epll_sysclk_configuration;
typedef Sysclk_status<0x2a64> Epll_sysclk_status;
typedef Sysclk_configuration<0x2aa0> Cpll_sysclk_configuration;
typedef Sysclk_status<0x2aa4> Cpll_sysclk_status;
typedef Sysclk_configuration<0x2ac0> Gpll_sysclk_configuration;
typedef Sysclk_status<0x2ac4> Gpll_sysclk_status;
typedef Configuration<0x4000> Gscl_configuration;
typedef Status<0x4004> Gscl_status;
typedef Configuration<0x4020> Isp_configuration;
typedef Status<0x4024> Isp_status;
typedef Configuration<0x4040> Mfc_configuration;
typedef Status<0x4044> Mfc_status;
typedef Configuration<0x4060> G3d_configuration;
typedef Status<0x4064> G3d_status;
typedef Configuration<0x40A0> Disp1_configuration;
typedef Status<0x40A4> Disp1_status;
typedef Configuration<0x40C0> Mau_configuration;
typedef Status<0x40C4> Mau_status;
template <typename C, typename S>
void _disable_domain()
{
if (read<typename S::Stat>() == 0)
return;
write<typename C::Local_pwr_cfg>(0);
while (read<typename S::Stat>() != 0) ;
}
template <typename C, typename S>
void _enable_domain()
{
if (read<typename S::Stat>() == 7)
return;
write<typename C::Local_pwr_cfg>(7);
while (read<typename S::Stat>() != 7) ;
}
void _enable(unsigned long id)
{
switch (id) {
case PWR_USB20:
write<Usbhost_phy_control::Enable>(1);
break;
case PWR_HDMI: {
_enable_domain<Disp1_configuration, Disp1_status>();
Hdmi_phy_control::access_t hpc = read<Hdmi_phy_control>();
Hdmi_phy_control::Div_ratio::set(hpc, 150);
Hdmi_phy_control::Enable::set(hpc, 1);
write<Hdmi_phy_control>(hpc);
break; }
default:
PWRN("Unsupported for %s", names[id].name);
}
}
void _disable(unsigned long id)
{
switch (id) {
case PWR_USB20:
write<Usbhost_phy_control::Enable>(0);
break;
default:
PWRN("Unsupported for %s", names[id].name);
}
}
public:
/**
* Constructor
*/
Pmu() : Genode::Attached_mmio(Genode::Board_base::PMU_MMIO_BASE,
Genode::Board_base::PMU_MMIO_SIZE)
{
write<Hdmi_phy_control ::Enable>(0);
write<Usbdrd_phy_control ::Enable>(0);
write<Usbhost_phy_control::Enable>(0);
write<Efnand_phy_control ::Enable>(0);
write<Adc_phy_control ::Enable>(0);
write<Mtcadc_phy_control ::Enable>(0);
write<Dptx_phy_control ::Enable>(0);
_disable_domain<Gscl_configuration, Gscl_status>();
_disable_domain<Isp_configuration, Isp_status>();
_disable_domain<Mfc_configuration, Mfc_status>();
_disable_domain<G3d_configuration, G3d_status>();
_disable_domain<Disp1_configuration, Disp1_status>();
_disable_domain<Mau_configuration, Mau_status>();
_disable_domain<Vpll_sysclk_configuration, Vpll_sysclk_status>();
_disable_domain<Epll_sysclk_configuration, Epll_sysclk_status>();
_disable_domain<Cpll_sysclk_configuration, Cpll_sysclk_status>();
_disable_domain<Gpll_sysclk_configuration, Gpll_sysclk_status>();
}
/********************************
** Regulator driver interface **
********************************/
void level(Regulator_id id, unsigned long level)
{
switch (id) {
default:
PWRN("Unsupported for %s", names[id].name);
}
}
unsigned long level(Regulator_id id)
{
switch (id) {
default:
PWRN("Unsupported for %s", names[id].name);
}
return 0;
}
void state(Regulator_id id, bool enable)
{
if (enable)
_enable(id);
else
_disable(id);
}
bool state(Regulator_id id)
{
switch (id) {
case PWR_USB20:
return read<Usbhost_phy_control::Enable>();
default:
PWRN("Unsupported for %s", names[id].name);
}
return true;
}
};
#endif /* _PMU_H_ */

View File

@ -0,0 +1,5 @@
TARGET = platform_drv
REQUIRES = platform_odroid_x2
SRC_CC = main.cc
INC_DIR += ${PRG_DIR}
LIBS = base

View File

@ -0,0 +1,7 @@
REPOSITORIES = $(GENODE_DIR)/repos/base-foc
##
## Kernel-specific run tool configuration
##
RUN_OPT = --include boot_dir/foc

View File

@ -44,6 +44,7 @@ usage:
@echo " 'foc_panda'"
@echo " 'foc_arndale'"
@echo " 'foc_rpi'"
@echo " 'foc_odroid_x2'"
@echo " 'sel4_x86_32'"
@echo " 'lx_hybrid_x86'"
@echo
@ -143,7 +144,7 @@ $(BUILD_DIR)/Makefile:
#
# Add 'ports-foc' repository to Fiasco.OC build directory
#
ifeq ($(filter-out foc_x86_32 foc_imx53 foc_pbxa9 foc_panda foc_arndale foc_rpi,$(PLATFORM)),)
ifeq ($(filter-out foc_x86_32 foc_imx53 foc_pbxa9 foc_panda foc_arndale foc_rpi foc_odroid_x2,$(PLATFORM)),)
$(BUILD_DIR)/etc/build.conf::
@cat $(BUILD_CONF).ports-foc >> $@
endif
@ -159,7 +160,7 @@ endif
#
# Add ARM drivers repositories to ARM build directories
#
ifeq ($(filter-out foc_panda foc_arndale hw_panda hw_arndale hw_odroid_xu foc_imx53 foc_rpi,$(PLATFORM)),)
ifeq ($(filter-out foc_panda foc_arndale hw_panda hw_arndale hw_odroid_xu foc_imx53 foc_rpi foc_odroid_x2,$(PLATFORM)),)
$(BUILD_DIR)/etc/build.conf::
@cat $(BUILD_CONF).drivers_arm >> $@
endif
@ -212,6 +213,9 @@ foc_arndale::
foc_rpi::
@echo "SPECS = genode foc_rpi" > $(BUILD_DIR)/etc/specs.conf
foc_odroid_x2::
@echo "SPECS = genode foc_odroid_x2" > $(BUILD_DIR)/etc/specs.conf
#
# On all other platforms, the performance counter is assumed to be active by
# default. On HW, its activation is done by an optional core lib. To be

View File

@ -50,7 +50,6 @@ proc run_power_on { } {
append qemu_args " -M realview-pbx-a9"
}
if {[have_spec platform_vpb926]} { append qemu_args " -M versatilepb -m 128 " }
if {[have_spec platform_vea9x4]} { append qemu_args " -M vexpress-a9 -cpu cortex-a9 -m 256 " }
if {[have_spec hw_x86_64]} {
regsub -all {\-m ([0-9])+} $qemu_args "" qemu_args
append qemu_args " -m 512 "