mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
parent
1dc9ab9a95
commit
65136c2289
@ -16,24 +16,24 @@
|
||||
|
||||
/* core includes */
|
||||
#include <board.h>
|
||||
#include <timer/exynos_pwm.h>
|
||||
#include <timer/exynos_mct.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/**
|
||||
* Kernel timer
|
||||
*/
|
||||
class Timer : public Exynos_pwm::Timer
|
||||
class Timer : public Exynos_mct::Timer
|
||||
{
|
||||
public:
|
||||
|
||||
enum { IRQ = Genode::Board::PWM_IRQ_0 };
|
||||
enum { IRQ = Genode::Board::MCT_IRQ_L0 };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Timer() : Exynos_pwm::Timer(Genode::Board::PWM_MMIO_BASE,
|
||||
Genode::Board::PWM_CLOCK) { }
|
||||
Timer() : Exynos_mct::Timer(Genode::Board::MCT_MMIO_BASE,
|
||||
Genode::Board::MCT_CLOCK) { }
|
||||
};
|
||||
}
|
||||
|
||||
|
160
base-hw/src/core/timer/exynos_mct.h
Normal file
160
base-hw/src/core/timer/exynos_mct.h
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* \brief Timer for core
|
||||
* \author Martin stein
|
||||
* \date 2013-01-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _TIMER__EXYNOS_MCT_H_
|
||||
#define _TIMER__EXYNOS_MCT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/mmio.h>
|
||||
|
||||
namespace Exynos_mct
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/**
|
||||
* Timer for core
|
||||
*/
|
||||
class Timer : public Mmio
|
||||
{
|
||||
enum {
|
||||
PRESCALER = 1,
|
||||
DIV_MUX = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* MCT configuration
|
||||
*/
|
||||
struct Mct_cfg : Register<0x0, 32>
|
||||
{
|
||||
struct Prescaler : Bitfield<0, 8> { };
|
||||
struct Div_mux : Bitfield<8, 3> { };
|
||||
struct Tick_mon_sel : Bitfield<11, 2> { };
|
||||
struct Int_mon_sel : Bitfield<13, 3> { };
|
||||
|
||||
/**
|
||||
* Initialization value
|
||||
*/
|
||||
static access_t init_value()
|
||||
{
|
||||
return Prescaler::bits(PRESCALER) |
|
||||
Div_mux::bits(DIV_MUX) |
|
||||
Tick_mon_sel::bits(0) |
|
||||
Int_mon_sel::bits(0);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Local timer 0 free running counter buffer
|
||||
*/
|
||||
struct L0_frcntb : Register<0x310, 32> { };
|
||||
|
||||
/**
|
||||
* Local timer 0 free running counter observation
|
||||
*/
|
||||
struct L0_frcnto : Register<0x314, 32> { };
|
||||
|
||||
/**
|
||||
* Local timer 0 configuration
|
||||
*/
|
||||
struct L0_tcon : Register<0x320, 32> {
|
||||
struct Frc_start : Bitfield<3, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Local timer 0 expired status
|
||||
*/
|
||||
struct L0_int_cstat : Register<0x330, 32, true> {
|
||||
struct Frcnt : Bitfield<1, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Local timer 0 interrupt enable
|
||||
*/
|
||||
struct L0_int_enb : Register<0x334, 32> {
|
||||
struct Frceie : Bitfield<1, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Local timer 0 write status
|
||||
*/
|
||||
struct L0_wstat : Register<0x340, 32, true> {
|
||||
struct Frcntb : Bitfield<2, 1> { };
|
||||
struct Tcon : Bitfield<3, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Write to reg that replies via ack bit and clear ack bit
|
||||
*/
|
||||
template <typename DEST, typename ACK>
|
||||
void _acked_write(typename DEST::Register_base::access_t const v)
|
||||
{
|
||||
typedef typename DEST::Register_base Dest;
|
||||
typedef typename ACK::Bitfield_base Ack;
|
||||
write<Dest>(v);
|
||||
while (!read<Ack>());
|
||||
write<Ack>(1);
|
||||
}
|
||||
|
||||
float const _tics_per_ms;
|
||||
|
||||
/**
|
||||
* Start and stop counting
|
||||
*/
|
||||
void _run(bool const run) {
|
||||
_acked_write<L0_tcon, L0_wstat::Tcon>
|
||||
(L0_tcon::Frc_start::bits(run)); }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Timer(addr_t const base, unsigned const clk)
|
||||
: Mmio(base), _tics_per_ms((float)clk / (PRESCALER + 1) / (1 << DIV_MUX) / 1000)
|
||||
{
|
||||
write<Mct_cfg>(Mct_cfg::init_value());
|
||||
write<L0_int_enb>(L0_int_enb::Frceie::bits(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a one-shot run
|
||||
*
|
||||
* \param tics native timer value used to assess the delay
|
||||
* of the timer interrupt as of the call
|
||||
*/
|
||||
inline void start_one_shot(unsigned const tics)
|
||||
{
|
||||
_run(0);
|
||||
_acked_write<L0_frcntb, L0_wstat::Frcntb>(tics);
|
||||
_run(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate milliseconds to a native timer value
|
||||
*/
|
||||
unsigned ms_to_tics(unsigned const ms) {
|
||||
return ms * _tics_per_ms; }
|
||||
|
||||
/**
|
||||
* Stop the timer and return last timer value
|
||||
*/
|
||||
unsigned stop_one_shot() { return read<L0_frcnto>(); }
|
||||
|
||||
/**
|
||||
* Clear interrupt output line
|
||||
*/
|
||||
void clear_interrupt() { write<L0_int_cstat::Frcnt>(1); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _TIMER__EXYNOS_MCT_H_ */
|
@ -1,166 +0,0 @@
|
||||
/*
|
||||
* \brief Timer for core
|
||||
* \author Martin stein
|
||||
* \date 2013-01-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _TIMER__EXYNOS_PWM_H_
|
||||
#define _TIMER__EXYNOS_PWM_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/mmio.h>
|
||||
|
||||
namespace Exynos_pwm
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/**
|
||||
* Timer for core
|
||||
*
|
||||
* Exynos 5 PWM timer provides 5 independent 32 bit down count timers.
|
||||
* This driver uses timer 0 only.
|
||||
*/
|
||||
class Timer : 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(0) |
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
float const _tics_per_ms;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Timer(addr_t const base, unsigned const clk)
|
||||
: Mmio(base), _tics_per_ms((float)clk / PRESCALER / 1000)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a one-shot run
|
||||
*
|
||||
* \param tics native timer value used to assess the delay
|
||||
* of the timer interrupt as of the call
|
||||
*/
|
||||
inline void start_one_shot(uint32_t const tics)
|
||||
{
|
||||
write<Cntb0>(tics);
|
||||
write<Con::Enable0>(0);
|
||||
write<Con::Update0>(1);
|
||||
write<Con::Update0>(0);
|
||||
write<Con::Enable0>(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate milliseconds to a native timer value
|
||||
*/
|
||||
uint32_t ms_to_tics(unsigned const ms) {
|
||||
return ms * _tics_per_ms; }
|
||||
|
||||
/**
|
||||
* Stop the timer and return last timer value
|
||||
*/
|
||||
unsigned stop_one_shot() { return read<Cnto0>(); }
|
||||
|
||||
/**
|
||||
* Clear interrupt output line
|
||||
*/
|
||||
void clear_interrupt() { write<Int::Stat0>(1); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _TIMER__EXYNOS_PWM_H_ */
|
||||
|
@ -41,8 +41,13 @@ namespace Genode
|
||||
|
||||
/* timer */
|
||||
PWM_MMIO_BASE = 0x12dd0000,
|
||||
PWM_MMIO_SIZE = 0x1000,
|
||||
PWM_CLOCK = 66000000,
|
||||
PWM_IRQ_0 = 68,
|
||||
MCT_MMIO_BASE = 0x101c0000,
|
||||
MCT_MMIO_SIZE = 0x1000,
|
||||
MCT_CLOCK = 24000000,
|
||||
MCT_IRQ_L0 = 152,
|
||||
|
||||
/* if board provides security extension */
|
||||
SECURITY_EXTENSION = 1,
|
||||
|
Loading…
Reference in New Issue
Block a user