sel4: add timer for imx7d_sabre

Fix #3292
This commit is contained in:
Stefan Kalkowski 2019-04-16 13:21:31 +02:00 committed by Christian Helmuth
parent 95b9e0a0e2
commit 4bcd9169c0
6 changed files with 194 additions and 2 deletions

View File

@ -0,0 +1 @@
include $(call select_from_repositories,src/timer/gpt/imx7/target.inc)

View File

@ -0,0 +1,9 @@
TARGET = imx7_timer_drv
REQUIRES = arm_v7
GEN_DIR := $(BASE_DIR)/src/timer
INC_DIR += $(GEN_DIR)/gpt
SRC_CC += gpt/time_source.cc gpt/imx7/timer.cc
include $(GEN_DIR)/target.inc
vpath %.cc $(GEN_DIR)

View File

@ -0,0 +1,29 @@
/*
* \brief Time source for i.MX7 (GPT1)
* \author Stefan Kalkowski
* \date 2019-04-13
*/
/*
* Copyright (C) 2019 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.
*/
/* local include */
#include <time_source.h>
using namespace Genode;
enum {
MMIO_BASE = 0x302d0000,
MMIO_SIZE = 0x1000,
IRQ = 87,
};
Timer::Time_source::Time_source(Env &env)
: Attached_mmio(env, MMIO_BASE, MMIO_SIZE),
Signalled_time_source(env),
_timer_irq(env, IRQ) { _initialize(); }

View File

@ -0,0 +1,76 @@
/*
* \brief Time source that uses the General Purpose Timer (Freescale)
* \author Stefan Kalkowski
* \date 2019-04-13
*/
/*
* Copyright (C) 2019 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.
*/
/* local includes */
#include <time_source.h>
using namespace Genode;
void Timer::Time_source::schedule_timeout(Genode::Microseconds duration,
Timeout_handler &handler)
{
_handler = &handler;
/* set to minimum ticks value to not miss a too short timeout */
Genode::uint32_t const ticks =
Genode::max(1UL, (duration.value * TICKS_PER_MS) / 1000);
/* clear interrupts */
if (read<Sr>()) {
write<Sr>(0xffffffff);
_timer_irq.ack_irq();
}
/* set new timeout */
write<Ocr1>(read<Cnt>() + ticks);
}
Duration Timer::Time_source::curr_time()
{
Cnt::access_t cur_cnt = read<Cnt>();
Genode::Microseconds us(timer_ticks_to_us(cur_cnt - _last_cnt,
TICKS_PER_MS));
_last_cnt = cur_cnt;
_curr_time.add(us);
return _curr_time;
}
Genode::Microseconds Timer::Time_source::max_timeout() const
{
static unsigned long max = timer_ticks_to_us(0xffffffff, TICKS_PER_MS);
return Genode::Microseconds(max);
}
void Timer::Time_source::_initialize()
{
_timer_irq.sigh(_signal_handler);
write<Cr>(0);
write<Ir>(0);
write<Ocr1>(0);
write<Ocr2>(0);
write<Ocr3>(0);
write<Icr1>(0);
write<Icr2>(0);
write<Cr::Clk_src>(Cr::Clk_src::HIGH_FREQ_REF_CLK);
while (read<Cr::Swr>()) ;
write<Sr>(0);
write<Cr::Frr>(1);
write<Cr::En_mod>(1);
write<Cr::En>(1);
write<Ir>(1);
}

View File

@ -0,0 +1,76 @@
/*
* \brief Time source that uses the General Purpose Timer (Freescale)
* \author Stefan Kalkowski
* \date 2019-04-13
*/
/*
* Copyright (C) 2019 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 _TIME_SOURCE_H_
#define _TIME_SOURCE_H_
/* Genode includes */
#include <irq_session/connection.h>
#include <os/attached_mmio.h>
#include <drivers/timer/util.h>
/* local includes */
#include <signalled_time_source.h>
namespace Timer { class Time_source; }
class Timer::Time_source : private Genode::Attached_mmio,
public Genode::Signalled_time_source
{
private:
enum { TICKS_PER_MS = 500 };
struct Cr : Register<0x0, 32>
{
struct En : Bitfield<0, 1> { };
struct En_mod : Bitfield<1, 1> { };
struct Clk_src : Bitfield<6, 3> { enum { HIGH_FREQ_REF_CLK = 2 }; };
struct Frr : Bitfield<9, 1> { };
struct Swr : Bitfield<15, 1> { };
};
struct Pr : Register<0x4, 32> { };
struct Sr : Register<0x8, 32> { };
struct Ir : Register<0xc, 32> { };
struct Ocr1 : Register<0x10, 32> { };
struct Ocr2 : Register<0x14, 32> { };
struct Ocr3 : Register<0x18, 32> { };
struct Icr1 : Register<0x1c, 32> { };
struct Icr2 : Register<0x20, 32> { };
struct Cnt : Register<0x24, 32> { };
Genode::Irq_connection _timer_irq;
Genode::Duration _curr_time { Genode::Microseconds(0) };
Cnt::access_t _last_cnt { 0 };
void _initialize();
public:
Time_source(Genode::Env &env);
/*************************
** Genode::Time_source **
*************************/
Genode::Duration curr_time() override;
void schedule_timeout(Genode::Microseconds duration,
Timeout_handler &handler) override;
Genode::Microseconds max_timeout() const override;
};
#endif /* _TIME_SOURCE_H_ */

View File

@ -1,8 +1,9 @@
proc binary_name_ld_lib_so { } { return "ld-sel4.lib.so" }
proc binary_name_core_o { } { return "core-sel4.o" }
proc binary_name_timer { } {
if {[have_spec imx6]} { return "imx6_timer_drv" }
if {[have_spec x86]} { return "pit_timer_drv" }
if {[have_spec imx6]} { return "imx6_timer_drv" }
if {[have_spec imx7d_sabre]} { return "imx7_timer_drv" }
if {[have_spec x86]} { return "pit_timer_drv" }
puts "unknown platform - no timer driver"
exit -1
}