/* * \brief Timer driver for core * \author Martin stein * \date 2013-01-10 */ /* * Copyright (C) 2013-2017 Genode Labs GmbH * * This file is part of the Kernel OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. */ #ifndef _SRC__CORE__SPEC__ARM__EXYNOS_MCT_H_ #define _SRC__CORE__SPEC__ARM__EXYNOS_MCT_H_ /* Kernel includes */ #include /* base-hw includes */ #include namespace Board { class Timer; } struct Board::Timer : Genode::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> { }; }; /***************** ** Local timer ** *****************/ enum Local_timer_offset { L0 = 0x300, L1 = 0x400 }; struct Local : Genode::Mmio { struct Tcntb : Register<0x0, 32> { }; struct Tcnto : Register<0x4, 32> { }; struct Icntb : Register<0x8, 32> { }; struct Icnto : Register<0xc, 32> { }; struct Frcntb : Register<0x10, 32> { }; struct Frcnto : Register<0x14, 32> { }; struct Tcon : Register<0x20, 32> { struct Timer_start : Bitfield<0, 1> { }; struct Irq_start : Bitfield<1, 1> { }; struct Irq_type : Bitfield<2, 1> { }; struct Frc_start : Bitfield<3, 1> { }; }; struct Int_cstat : Register<0x30, 32, true> { struct Intcnt : Bitfield<0, 1> { }; struct Frccnt : Bitfield<1, 1> { }; }; struct Int_enb : Register<0x34, 32> { struct Inteie : Bitfield<0, 1> { }; struct Frceie : Bitfield<1, 1> { }; }; struct Wstat : Register<0x40, 32, true> { struct Tcntb : Bitfield<0, 1> { }; struct Icntb : Bitfield<1, 1> { }; struct Frcntb : Bitfield<2, 1> { }; struct Tcon : Bitfield<3, 1> { }; }; Tcnto::access_t cnt = { 0 }; /** * Write to reg that replies via ack bit and clear ack bit */ template void acked_write(typename DEST::Register_base::access_t const v) { typedef typename DEST::Register_base Dest; typedef typename ACK::Bitfield_base Ack; write(v); while (!read()); write(1); } void update_cnt() { cnt = read(); } Local(Genode::addr_t base); }; /** * Calculate amount of ticks per ms for specific input clock * * \param clock input clock */ Kernel::time_t static calc_ticks_per_ms(unsigned const clock) { return clock / (PRESCALER + 1) / (1 << DIV_MUX) / 1000; } Local local; unsigned const ticks_per_ms; unsigned const cpu_id; Timer(unsigned cpu_id); }; #endif /* _SRC__CORE__SPEC__ARM__EXYNOS_MCT_H_ */