parent
65136c2289
commit
a0d182e25a
|
@ -66,6 +66,7 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||||
static Native_region _regions[] =
|
static Native_region _regions[] =
|
||||||
{
|
{
|
||||||
{ Board::GIC_CPU_MMIO_BASE, Board::GIC_CPU_MMIO_SIZE },
|
{ Board::GIC_CPU_MMIO_BASE, Board::GIC_CPU_MMIO_SIZE },
|
||||||
|
{ Board::MCT_MMIO_BASE, Board::MCT_MMIO_SIZE },
|
||||||
};
|
};
|
||||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||||
}
|
}
|
||||||
|
|
3
os/lib/mk/hw_arndale/timer.mk
Normal file
3
os/lib/mk/hw_arndale/timer.mk
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
INC_DIR += $(REP_DIR)/src/drivers/timer/hw $(REP_DIR)/src/drivers/timer/hw/exynos5
|
||||||
|
|
||||||
|
include $(REP_DIR)/lib/mk/timer.inc
|
211
os/src/drivers/timer/hw/exynos5/platform_timer_base.h
Normal file
211
os/src/drivers/timer/hw/exynos5/platform_timer_base.h
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
/*
|
||||||
|
* \brief Basic driver behind platform timer
|
||||||
|
* \author Martin stein
|
||||||
|
* \date 2013-04-04
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 _HW__EXYNOS5__PLATFORM_TIMER_BASE_H_
|
||||||
|
#define _HW__EXYNOS5__PLATFORM_TIMER_BASE_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <io_mem_session/connection.h>
|
||||||
|
#include <irq_session/connection.h>
|
||||||
|
#include <drivers/board_base.h>
|
||||||
|
#include <util/mmio.h>
|
||||||
|
|
||||||
|
namespace Genode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Exynos 5250 pulse width modulation timer
|
||||||
|
*/
|
||||||
|
class Pwm : public Mmio
|
||||||
|
{
|
||||||
|
enum { PRESCALER = 2 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer configuration 0
|
||||||
|
*/
|
||||||
|
struct Cfg0 : Register<0x0, 32>
|
||||||
|
{
|
||||||
|
struct Prescaler0 : Bitfield<0, 8>
|
||||||
|
{
|
||||||
|
enum { DEFAULT = PRESCALER - 1 };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer configuration 1
|
||||||
|
*/
|
||||||
|
struct Cfg1 : Register<0x4, 32>
|
||||||
|
{
|
||||||
|
struct Div0 : Bitfield<0, 4> { enum { DISABLE = 0 }; };
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer control
|
||||||
|
*/
|
||||||
|
struct Con : Register<0x8, 32>
|
||||||
|
{
|
||||||
|
struct Enable0 : Bitfield<0, 1> { };
|
||||||
|
struct Update0 : Bitfield<1, 1> { };
|
||||||
|
struct Invert_tout0 : Bitfield<2, 1> { };
|
||||||
|
struct Auto_reload0 : Bitfield<3, 1> { };
|
||||||
|
struct Deadzone_en : Bitfield<4, 1> { };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization value
|
||||||
|
*/
|
||||||
|
static access_t init_value()
|
||||||
|
{
|
||||||
|
return Invert_tout0::bits(0) |
|
||||||
|
Auto_reload0::bits(1) |
|
||||||
|
Deadzone_en::bits(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer 0 count buffer
|
||||||
|
*/
|
||||||
|
struct Cntb0 : Register<0xc, 32> { };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer 0 compare buffer
|
||||||
|
*/
|
||||||
|
struct Cmpb0 : Register<0x10, 32> { };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer 0 count observation
|
||||||
|
*/
|
||||||
|
struct Cnto0 : Register<0x14, 32> { };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer IRQ control and status
|
||||||
|
*/
|
||||||
|
struct Int : Register<0x44, 32>
|
||||||
|
{
|
||||||
|
struct En0 : Bitfield<0, 1> { };
|
||||||
|
struct En1 : Bitfield<1, 1> { };
|
||||||
|
struct En2 : Bitfield<2, 1> { };
|
||||||
|
struct En3 : Bitfield<3, 1> { };
|
||||||
|
struct En4 : Bitfield<4, 1> { };
|
||||||
|
struct Stat0 : Bitfield<5, 1> { };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization value
|
||||||
|
*/
|
||||||
|
static access_t init_value()
|
||||||
|
{
|
||||||
|
return En0::bits(1) |
|
||||||
|
En1::bits(0) |
|
||||||
|
En2::bits(0) |
|
||||||
|
En3::bits(0) |
|
||||||
|
En4::bits(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer tics per microsecond
|
||||||
|
*/
|
||||||
|
static float tics_per_us() {
|
||||||
|
return (float)Board_base::PWM_CLOCK / PRESCALER / 1000 / 1000; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Microseconds per timer tic
|
||||||
|
*/
|
||||||
|
static float us_per_tic() { return (float)1 / tics_per_us(); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* \param base MMIO base
|
||||||
|
*/
|
||||||
|
Pwm(addr_t const base) : Mmio(base)
|
||||||
|
{
|
||||||
|
write<Cfg0::Prescaler0>(Cfg0::Prescaler0::DEFAULT);
|
||||||
|
write<Cfg1::Div0>(Cfg1::Div0::DISABLE);
|
||||||
|
write<Int>(Int::init_value());
|
||||||
|
write<Con>(Con::init_value());
|
||||||
|
write<Cmpb0>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count down 'value', raise IRQ output, wrap counter and continue
|
||||||
|
*/
|
||||||
|
void run_and_wrap(unsigned long value)
|
||||||
|
{
|
||||||
|
write<Cntb0>(value);
|
||||||
|
write<Con::Enable0>(0);
|
||||||
|
write<Con::Update0>(1);
|
||||||
|
write<Con::Update0>(0);
|
||||||
|
write<Int::Stat0>(1);
|
||||||
|
write<Cntb0>(max_value());
|
||||||
|
write<Con::Enable0>(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum timeout value
|
||||||
|
*/
|
||||||
|
unsigned long max_value() const { return (Cntb0::access_t)~0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate timer tics to microseconds
|
||||||
|
*/
|
||||||
|
unsigned long tics_to_us(unsigned long const tics) const
|
||||||
|
{
|
||||||
|
float const us = tics * us_per_tic();
|
||||||
|
return (unsigned long)us;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate microseconds to timer tics
|
||||||
|
*/
|
||||||
|
unsigned long us_to_tics(unsigned long const us)
|
||||||
|
{
|
||||||
|
float const tics = us * tics_per_us();
|
||||||
|
return (unsigned long)tics;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sample the timer counter and according wrapped status
|
||||||
|
*/
|
||||||
|
unsigned long value(bool & wrapped) const
|
||||||
|
{
|
||||||
|
unsigned long v = read<Cnto0>();
|
||||||
|
wrapped = (bool)read<Int::Stat0>();
|
||||||
|
return wrapped ? read<Cnto0>() : v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic driver behind platform timer
|
||||||
|
*/
|
||||||
|
class Platform_timer_base : public Genode::Io_mem_connection,
|
||||||
|
public Genode::Pwm
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum { IRQ = Genode::Board_base::PWM_IRQ_0 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
Platform_timer_base()
|
||||||
|
: Io_mem_connection(Genode::Board_base::PWM_MMIO_BASE,
|
||||||
|
Genode::Board_base::PWM_MMIO_SIZE),
|
||||||
|
Genode::Pwm((Genode::addr_t)Genode::env()->rm_session()
|
||||||
|
->attach(dataspace()))
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _HW__EXYNOS5__PLATFORM_TIMER_BASE_H_ */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user