mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-21 03:55:04 +00:00
parent
6776d6c9a8
commit
433f859cb9
@ -3,7 +3,7 @@
|
||||
* \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
|
||||
* \date 2015-07-08
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -30,12 +30,16 @@ struct Genode::Board_base : Exynos4
|
||||
enum
|
||||
{
|
||||
/* clock management unit */
|
||||
CMU_MMIO_BASE = 0x10040000,
|
||||
CMU_MMIO_BASE = 0x10030000,
|
||||
CMU_MMIO_SIZE = 0x18000,
|
||||
|
||||
/* power management unit */
|
||||
PMU_MMIO_BASE = 0x10020000,
|
||||
|
||||
PMU_MMIO_SIZE = 0x5000,
|
||||
|
||||
/* USB HOST interrupt */
|
||||
USB_HOST20_IRQ = 102,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -3,11 +3,11 @@
|
||||
# \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
|
||||
# \date 2015-07-08
|
||||
#
|
||||
|
||||
# denote specs that are fullfilled by this spec
|
||||
SPECS += exynos4 cortex_a9
|
||||
SPECS += exynos4 cortex_a9 usb
|
||||
|
||||
# add repository relative paths
|
||||
REP_INC_DIR += include/platform/odroid_x2
|
||||
|
@ -2,6 +2,7 @@ proc have_platform_drv {} {
|
||||
if {[have_spec linux]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
return [expr [have_spec platform_arndale] \
|
||||
|| [have_spec platform_imx53] \
|
||||
|| [have_spec platform_rpi] \
|
||||
|
29
repos/dde_linux/include/usb/platform_odroid_x2/usb_masks.h
Normal file
29
repos/dde_linux/include/usb/platform_odroid_x2/usb_masks.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* \brief USB registers masks for Odroid-x2
|
||||
* \author Alexy Gallardo Segura <alexy@uclv.cu>
|
||||
* \author Humberto Lopez Leon <humberto@uclv.cu>
|
||||
* \author Reinir Millo Sanchez <rmillo@uclv.cu>
|
||||
* \date 2015-07-08
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _USB_MASKS_H_
|
||||
#define _USB_MASKS_H_
|
||||
|
||||
enum {
|
||||
PHY0_NORMAL_MASK = 0x39 << 0,
|
||||
PHY0_SWRST_MASK = 0x7 << 0,
|
||||
PHY1_STD_NORMAL_MASK = 0x7 << 6,
|
||||
EXYNOS4X12_HSIC0_NORMAL_MASK = 0x7 << 9,
|
||||
EXYNOS4X12_HSIC1_NORMAL_MASK = 0x7 << 12,
|
||||
EXYNOS4X12_HOST_LINK_PORT_SWRST_MASK = 0xf << 7,
|
||||
EXYNOS4X12_PHY1_SWRST_MASK = 0xf << 3,
|
||||
};
|
||||
|
||||
#endif /* _USB_MASKS_H_ */
|
4
repos/dde_linux/lib/mk/platform_odroid_x2/usb-stat.mk
Normal file
4
repos/dde_linux/lib/mk/platform_odroid_x2/usb-stat.mk
Normal file
@ -0,0 +1,4 @@
|
||||
LIBS += net-stat
|
||||
CC_OPT += -DGENODE_NET_STAT
|
||||
|
||||
include $(REP_DIR)/lib/mk/platform_odroid_x2/usb.mk
|
15
repos/dde_linux/lib/mk/platform_odroid_x2/usb.mk
Normal file
15
repos/dde_linux/lib/mk/platform_odroid_x2/usb.mk
Normal file
@ -0,0 +1,15 @@
|
||||
SRC_C += $(addprefix net/usb/, usbnet.c smsc95xx.c)
|
||||
SRC_C += usb/host/ehci-exynos.c
|
||||
|
||||
include $(REP_DIR)/lib/mk/usb.inc
|
||||
include $(REP_DIR)/lib/mk/armv7/usb.inc
|
||||
|
||||
|
||||
CC_OPT += -DCONFIG_USB_EHCI_TT_NEWSCHED \
|
||||
-DCONFIG_USB_OTG_UTILS
|
||||
|
||||
SRC_CC += platform.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/include/usb/platform_odroid_x2
|
||||
|
||||
vpath platform.cc $(LIB_DIR)/arm/platform_odroid_x2
|
296
repos/dde_linux/src/lib/usb/arm/platform_odroid_x2/platform.cc
Normal file
296
repos/dde_linux/src/lib/usb/arm/platform_odroid_x2/platform.cc
Normal file
@ -0,0 +1,296 @@
|
||||
/*
|
||||
* \brief EHCI for Odroid-x2 initializaion code
|
||||
* \author Sebastian Sumpf
|
||||
* \author Alexy Gallardo Segura <alexy@uclv.cu>
|
||||
* \author Humberto Lopez Leon <humberto@uclv.cu>
|
||||
* \author Reinir Millo Sanchez <rmillo@uclv.cu>
|
||||
* \date 2015-07-08
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Genode */
|
||||
#include <drivers/board_base.h>
|
||||
#include <os/attached_io_mem_dataspace.h>
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <regulator/consts.h>
|
||||
#include <regulator_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <util/mmio.h>
|
||||
|
||||
/* Emulation */
|
||||
#include <platform/platform.h>
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
#include <platform.h>
|
||||
|
||||
#include <usb_masks.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
enum {
|
||||
/*The EHCI base is taken from linux kernel */
|
||||
EHCI_BASE = 0x12580000,
|
||||
GPIO_BASE = 0x11000000,
|
||||
USBOTG = 0x125B0000,
|
||||
EHCI_IRQ = Board_base::USB_HOST20_IRQ,
|
||||
};
|
||||
|
||||
static resource _ehci[] =
|
||||
{
|
||||
{ EHCI_BASE, EHCI_BASE + 0xfff, "ehci", IORESOURCE_MEM },
|
||||
{ EHCI_IRQ, EHCI_IRQ, "ehci-irq", IORESOURCE_IRQ },
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* EHCI controller
|
||||
*/
|
||||
struct Ehci : Genode::Mmio
|
||||
{
|
||||
Ehci(addr_t const mmio_base) : Mmio(mmio_base)
|
||||
{
|
||||
write<Cmd>(0);
|
||||
|
||||
/* reset */
|
||||
write<Cmd::Reset>(1);
|
||||
|
||||
while(read<Cmd::Reset>())
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
struct Cmd : Register<0x10, 32>
|
||||
{
|
||||
struct Reset : Bitfield<1, 1> { };
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Gpio ETC6 register handling
|
||||
*/
|
||||
|
||||
struct Etc6 : Genode::Mmio
|
||||
{
|
||||
Etc6(Genode::addr_t base):Genode::Mmio (base)
|
||||
{
|
||||
unsigned int value;
|
||||
value = read<Pud>();
|
||||
write<Pud>((value & ~(0x3 << 14)) | (0x3 << 14));
|
||||
value = read<Pud>();
|
||||
}
|
||||
struct Pud : Register<0x0228, 16>{};
|
||||
};
|
||||
|
||||
/**
|
||||
* USB OTG handling
|
||||
*/
|
||||
struct Usb_Otg : Genode::Mmio
|
||||
{
|
||||
Usb_Otg(Genode::addr_t base):Genode::Mmio (base)
|
||||
{
|
||||
Timer::Connection timer;
|
||||
unsigned int rstcon_mask = 0;
|
||||
unsigned int phyclk_mask = 5;
|
||||
unsigned int phypwr_mask = 0;
|
||||
|
||||
/*set the clock of device*/
|
||||
write<Phyclk>(phyclk_mask);
|
||||
rstcon_mask= read<Phyclk>();
|
||||
|
||||
/* set to normal of Device */
|
||||
phypwr_mask= read<Phypwr>() & ~PHY0_NORMAL_MASK;
|
||||
write<Phypwr>(phypwr_mask);
|
||||
|
||||
/* set to normal of Host */
|
||||
phypwr_mask=read<Phypwr>();
|
||||
phypwr_mask &= ~(PHY1_STD_NORMAL_MASK
|
||||
|EXYNOS4X12_HSIC0_NORMAL_MASK
|
||||
|EXYNOS4X12_HSIC1_NORMAL_MASK);
|
||||
write<Phypwr>(phypwr_mask);
|
||||
|
||||
/* reset both PHY and Link of Device */
|
||||
rstcon_mask = read<Rstcon>() | PHY0_SWRST_MASK;
|
||||
write<Rstcon>(rstcon_mask);
|
||||
timer.usleep(10);
|
||||
rstcon_mask &= ~PHY0_SWRST_MASK;
|
||||
write<Rstcon>(rstcon_mask);
|
||||
|
||||
/* reset both PHY and Link of Host */
|
||||
rstcon_mask = read<Rstcon>()
|
||||
|EXYNOS4X12_HOST_LINK_PORT_SWRST_MASK
|
||||
|EXYNOS4X12_PHY1_SWRST_MASK;
|
||||
write<Rstcon>(rstcon_mask);
|
||||
timer.usleep(10);
|
||||
rstcon_mask &= ~(EXYNOS4X12_HOST_LINK_PORT_SWRST_MASK
|
||||
|EXYNOS4X12_PHY1_SWRST_MASK);
|
||||
write<Rstcon>(rstcon_mask);
|
||||
timer.usleep(10);
|
||||
}
|
||||
struct Phypwr : Register <0x0,32>{};
|
||||
struct Phyclk : Register <0x4,32>{};
|
||||
struct Rstcon : Register <0x8,32>{};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gpio handling
|
||||
*/
|
||||
|
||||
class Gpio_bank : Genode::Mmio
|
||||
{
|
||||
public:
|
||||
Gpio_bank(Genode::addr_t base):Genode::Mmio (base){}
|
||||
|
||||
struct Con : Register<0x0C60, 32>{};
|
||||
struct Dat : Register<0x0C64, 32>{};
|
||||
|
||||
void setDirection(int gpio , int en)
|
||||
{
|
||||
unsigned int value;
|
||||
enum { GPIO_OUTPUT = 0x1 };
|
||||
|
||||
value = read<Dat>();
|
||||
value &= ~(0x1 << gpio);
|
||||
if (en)
|
||||
value |= 0x1 << gpio;
|
||||
write<Dat>(value);
|
||||
configurePin(gpio, GPIO_OUTPUT);
|
||||
write<Dat>(value);
|
||||
}
|
||||
|
||||
private:
|
||||
void configurePin(int gpio, int cfg)
|
||||
{
|
||||
unsigned int value;
|
||||
|
||||
value = read<Con>();
|
||||
value &= ~con_mask(gpio);
|
||||
value |= con_sfr(gpio, cfg);
|
||||
write<Con>(value);
|
||||
}
|
||||
static inline
|
||||
unsigned con_mask(unsigned val) { return 0xf << ((val) << 2); }
|
||||
|
||||
static inline
|
||||
unsigned con_sfr(unsigned x, unsigned v) { return (v) << ((x) << 2); }
|
||||
};
|
||||
|
||||
static void clock_pwr_init()
|
||||
{
|
||||
/*Initialization of register etc6*/
|
||||
Io_mem_connection io_gpio(GPIO_BASE, 0x1000);
|
||||
addr_t gpio_base = (addr_t)env()->rm_session()->attach(io_gpio.dataspace());
|
||||
Etc6 etc6(gpio_base);
|
||||
env()->rm_session()->detach(gpio_base);
|
||||
|
||||
/* enable USB2 clock and power up */
|
||||
static Regulator::Connection reg_clk(Regulator::CLK_USB20);
|
||||
reg_clk.state(true);
|
||||
|
||||
static Regulator::Connection reg_pwr(Regulator::PWR_USB20);
|
||||
reg_pwr.state(true);
|
||||
}
|
||||
|
||||
static void usb_phy_init()
|
||||
{
|
||||
Io_mem_connection io_usbotg(USBOTG, 0x1000);
|
||||
addr_t usbotg_base = (addr_t)env()->rm_session()->attach(io_usbotg.dataspace());
|
||||
Usb_Otg usbotg(usbotg_base);
|
||||
env()->rm_session()->detach(usbotg_base);
|
||||
}
|
||||
|
||||
static void odroidx2_ehci_init()
|
||||
{
|
||||
clock_pwr_init();
|
||||
usb_phy_init();
|
||||
|
||||
/* reset hub via GPIO */
|
||||
Io_mem_connection io_gpio(GPIO_BASE, 0x1000);
|
||||
addr_t gpio_base = (addr_t)env()->rm_session()->attach(io_gpio.dataspace());
|
||||
|
||||
Gpio_bank x3(gpio_base);
|
||||
|
||||
/* Set Ref freq 0 => 24MHz, 1 => 26MHz*/
|
||||
/* Odroid Us have it at 24MHz, Odroid Xs at 26MHz */
|
||||
x3.setDirection(0,1);
|
||||
|
||||
/* Disconnect, Reset, Connect */
|
||||
x3.setDirection(4,0);
|
||||
x3.setDirection(5,0);
|
||||
x3.setDirection(5,1);
|
||||
x3.setDirection(4,1);
|
||||
env()->rm_session()->detach(gpio_base);
|
||||
|
||||
/* reset ehci controller */
|
||||
Io_mem_connection io_ehci(EHCI_BASE, 0x1000);
|
||||
addr_t ehci_base = (addr_t)env()->rm_session()->attach(io_ehci.dataspace());
|
||||
|
||||
Ehci ehci(ehci_base);
|
||||
|
||||
env()->rm_session()->detach(ehci_base);
|
||||
}
|
||||
|
||||
extern "C" void module_ehci_exynos_init();
|
||||
extern "C" int module_usbnet_init();
|
||||
extern "C" int module_smsc95xx_driver_init();
|
||||
|
||||
|
||||
void ehci_setup(Services *services)
|
||||
{
|
||||
|
||||
/* register network */
|
||||
if (services->nic){
|
||||
module_usbnet_init();
|
||||
module_smsc95xx_driver_init();
|
||||
}
|
||||
|
||||
/* register EHCI controller */
|
||||
module_ehci_exynos_init();
|
||||
|
||||
/* setup controller */
|
||||
odroidx2_ehci_init();
|
||||
|
||||
/* setup EHCI-controller platform device */
|
||||
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
|
||||
pdev->name = (char *)"exynos-ehci";
|
||||
pdev->id = 0;
|
||||
pdev->num_resources = 2;
|
||||
pdev->resource = _ehci;
|
||||
|
||||
/*needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c' */
|
||||
static u64 dma_mask = ~(u64)0;
|
||||
pdev->dev.dma_mask = &dma_mask;
|
||||
pdev->dev.coherent_dma_mask = ~0;
|
||||
|
||||
platform_device_register(pdev);
|
||||
}
|
||||
|
||||
void platform_hcd_init(Services *services)
|
||||
{
|
||||
/* register network */
|
||||
if (services->nic){
|
||||
module_usbnet_init();
|
||||
module_smsc95xx_driver_init();
|
||||
}
|
||||
/* register ehci */
|
||||
if (services->ehci)
|
||||
ehci_setup(services);
|
||||
}
|
||||
|
||||
Genode::Irq_session_capability platform_irq_activate(int irq)
|
||||
{
|
||||
try {
|
||||
Genode::Irq_connection conn(irq);
|
||||
conn.on_destruction(Genode::Irq_connection::KEEP_OPEN);
|
||||
return conn;
|
||||
} catch (...) { }
|
||||
|
||||
return Genode::Irq_session_capability();
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
* \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
|
||||
* \date 2015-07-08
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -58,9 +58,10 @@ class Cmu : public Regulator::Driver,
|
||||
** CMU CPU registers **
|
||||
***********************/
|
||||
typedef Pll_lock<4000> Apll_lock;
|
||||
typedef Pll_con0<0x4100> Apll_con0;
|
||||
typedef Pll_con0<0x14100> Apll_con0;
|
||||
|
||||
struct Clk_src_cpu : Register<0x4200, 32>
|
||||
|
||||
struct Clk_src_cpu : Register<0x14200, 32>
|
||||
{
|
||||
struct Mux_core_sel : Bitfield<16, 1>
|
||||
{
|
||||
@ -68,28 +69,30 @@ class Cmu : public Regulator::Driver,
|
||||
};
|
||||
};
|
||||
|
||||
struct Clk_mux_stat_cpu : Register<0x4400, 32>
|
||||
struct Clk_mux_stat_cpu : Register<0x14400, 32>
|
||||
{
|
||||
|
||||
struct Core_sel : Bitfield<16, 3>
|
||||
{
|
||||
enum { MOUT_APLL = 0b1, SCLK_MPLL = 0b10 };
|
||||
};
|
||||
};
|
||||
|
||||
struct Clk_div_cpu0 : Register<0x4500, 32>
|
||||
struct Clk_div_cpu0 : Register<0x14500, 32>
|
||||
{
|
||||
/* Cpu0 divider values for frequencies 200 - 1400 */
|
||||
static const Genode::uint32_t values[];
|
||||
};
|
||||
|
||||
struct Clk_div_cpu1 : Register<0x4504, 32>
|
||||
struct Clk_div_cpu1 : Register<0x14504, 32>
|
||||
{
|
||||
/* Divider for cpu1 doesn't change */
|
||||
enum { FIX_VALUE = 32 };
|
||||
};
|
||||
|
||||
struct Clk_div_stat_cpu0 : Register<0x4600, 32>
|
||||
struct Clk_div_stat_cpu0 : Register<0x14600, 32>
|
||||
{
|
||||
|
||||
struct Div_core : Bitfield< 0, 1> {};
|
||||
struct Div_corem0 : Bitfield< 4, 1> {};
|
||||
struct Div_corem1 : Bitfield< 8, 1> {};
|
||||
@ -99,6 +102,7 @@ class Cmu : public Regulator::Driver,
|
||||
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) |
|
||||
@ -112,7 +116,7 @@ class Cmu : public Regulator::Driver,
|
||||
}
|
||||
};
|
||||
|
||||
struct Clk_div_stat_cpu1 : Register<0x4604, 32>
|
||||
struct Clk_div_stat_cpu1 : Register<0x14604, 32>
|
||||
{
|
||||
struct Div_copy : Bitfield<0, 1> { };
|
||||
struct Div_hpm : Bitfield<4, 1> { };
|
||||
@ -128,18 +132,37 @@ class Cmu : public Regulator::Driver,
|
||||
/************************
|
||||
** CMU CORE registers **
|
||||
************************/
|
||||
|
||||
typedef Pll_lock<0x0008> Mpll_lock;
|
||||
typedef Pll_con0<0x0108> Mpll_con0;
|
||||
|
||||
struct Clk_src_dmc : Register<0x4200, 32>
|
||||
struct Clk_src_dmc : Register<0x10200, 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_acp : Register<0x0900, 32> { };
|
||||
struct Clk_gate_ip_isp0 : Register<0x8800, 32> { };
|
||||
struct Clk_gate_ip_isp1 : Register<0x8804, 32> { };
|
||||
|
||||
|
||||
|
||||
/***********************
|
||||
** CMU TOP registers **
|
||||
***********************/
|
||||
|
||||
struct Clk_gate_ip_fsys : Register<0xC940, 32>
|
||||
{
|
||||
struct Usbhost20 : Bitfield<12, 1> { };
|
||||
struct Usbdevice : Bitfield<13, 1> { };
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************
|
||||
** CPU functions **
|
||||
*******************/
|
||||
@ -148,7 +171,7 @@ class Cmu : public Regulator::Driver,
|
||||
|
||||
void _cpu_clk_freq(unsigned long level)
|
||||
{
|
||||
PINF("Setting CPU frequency %lu\n",level);
|
||||
PINF("Changing CPU frequency to %lu",level);
|
||||
unsigned freq;
|
||||
switch (level) {
|
||||
case CPU_FREQ_200:
|
||||
@ -218,6 +241,34 @@ class Cmu : public Regulator::Driver,
|
||||
!= Clk_mux_stat_cpu::Core_sel::MOUT_APLL) ;
|
||||
|
||||
_cpu_freq = static_cast<Cpu_clock_freq>(level);
|
||||
PINF("End of Changing CPU frequency to %lu",level);
|
||||
}
|
||||
|
||||
|
||||
void _enable(Regulator_id id)
|
||||
{
|
||||
switch (id) {
|
||||
case CLK_USB20:
|
||||
{
|
||||
write<Clk_gate_ip_fsys::Usbdevice>(1);
|
||||
return write<Clk_gate_ip_fsys::Usbhost20>(1);
|
||||
}
|
||||
default:
|
||||
PWRN("Unsupported for %s", names[id].name);
|
||||
}
|
||||
}
|
||||
|
||||
void _disable(Regulator_id id)
|
||||
{
|
||||
switch (id) {
|
||||
case CLK_USB20:
|
||||
{
|
||||
write<Clk_gate_ip_fsys::Usbdevice>(0);
|
||||
return write<Clk_gate_ip_fsys::Usbhost20>(0);
|
||||
}
|
||||
default:
|
||||
PWRN("Unsupported for %s", names[id].name);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
@ -230,9 +281,19 @@ class Cmu : public Regulator::Driver,
|
||||
Genode::Board_base::CMU_MMIO_SIZE),
|
||||
_cpu_freq(CPU_FREQ_1400)
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Close certain clock gates by default (~ 0.7 Watt reduction)
|
||||
*/
|
||||
|
||||
write<Clk_gate_ip_fsys>(0);
|
||||
|
||||
/**
|
||||
* Set default CPU frequency
|
||||
*/
|
||||
|
||||
|
||||
_cpu_clk_freq(_cpu_freq);
|
||||
|
||||
}
|
||||
@ -265,10 +326,21 @@ class Cmu : public Regulator::Driver,
|
||||
|
||||
void state(Regulator_id id, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
_enable(id);
|
||||
else
|
||||
_disable(id);
|
||||
}
|
||||
|
||||
bool state(Regulator_id id)
|
||||
{
|
||||
|
||||
switch (id) {
|
||||
case CLK_USB20:
|
||||
return read<Clk_gate_ip_fsys::Usbhost20>();
|
||||
default:
|
||||
PWRN("Unsupported for %s", names[id].name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -3,7 +3,7 @@
|
||||
* \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
|
||||
* \date 2015-07-08
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -24,14 +24,17 @@
|
||||
|
||||
struct Driver_factory: Regulator::Driver_factory
|
||||
{
|
||||
|
||||
Cmu _cmu;
|
||||
Pmu _pmu;
|
||||
|
||||
Regulator::Driver &create(Regulator::Regulator_id id)
|
||||
{
|
||||
switch (id) {
|
||||
case Regulator::CLK_CPU:
|
||||
case Regulator::CLK_USB20:
|
||||
return _cmu;
|
||||
case Regulator::PWR_USB20:
|
||||
return _pmu;
|
||||
default:
|
||||
throw Root::Invalid_args(); /* invalid regulator */
|
||||
};
|
||||
@ -39,14 +42,13 @@ struct Driver_factory: Regulator::Driver_factory
|
||||
|
||||
void destroy(Regulator::Driver &driver) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
PINF("--- Odroid-x2 platform driver ---\n");
|
||||
PINF("--- Odroid-x2 platform driver ---");
|
||||
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, 4096, "odroid_x2_plat_ep");
|
||||
@ -54,6 +56,7 @@ int main(int, char **)
|
||||
static Regulator::Root reg_root(&ep, env()->heap(), driver_factory);
|
||||
env()->parent()->announce(ep.manage(®_root));
|
||||
|
||||
PINF("--- Odroid-x2 platform driver. Done ---");
|
||||
sleep_forever();
|
||||
return 0;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
* \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
|
||||
* \date 2015-07-08
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -65,68 +65,19 @@ class Pmu : public Regulator::Driver,
|
||||
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 Control<0x0704> Usbdrd_phy_control;
|
||||
typedef Control<0x0708> Usbhost_phy1_control;
|
||||
typedef Control<0x70c> Usbhost_phy2_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);
|
||||
write<Usbdrd_phy_control::Enable>(1);
|
||||
write<Usbhost_phy1_control::Enable>(1);
|
||||
write<Usbhost_phy2_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);
|
||||
}
|
||||
@ -136,7 +87,9 @@ class Pmu : public Regulator::Driver,
|
||||
{
|
||||
switch (id) {
|
||||
case PWR_USB20:
|
||||
write<Usbhost_phy_control::Enable>(0);
|
||||
write<Usbdrd_phy_control::Enable>(0);
|
||||
write<Usbhost_phy1_control::Enable>(0);
|
||||
write<Usbhost_phy2_control::Enable>(0);
|
||||
break;
|
||||
default:
|
||||
PWRN("Unsupported for %s", names[id].name);
|
||||
@ -151,26 +104,9 @@ class Pmu : public Regulator::Driver,
|
||||
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>();
|
||||
write<Usbhost_phy1_control::Enable>(0);
|
||||
write<Usbhost_phy2_control::Enable>(0);
|
||||
}
|
||||
|
||||
|
||||
@ -207,7 +143,7 @@ class Pmu : public Regulator::Driver,
|
||||
{
|
||||
switch (id) {
|
||||
case PWR_USB20:
|
||||
return read<Usbhost_phy_control::Enable>();
|
||||
return read<Usbdrd_phy_control::Enable>();
|
||||
default:
|
||||
PWRN("Unsupported for %s", names[id].name);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user