embox
1/**
2* @file
3* @brief PowerPC Microprocessor Family clock device driver
4*
5* @date 06.11.12
6* @author Ilia Vaprol
7*/
8
9#include <asm/psr.h>10#include <asm/regs.h>11#include <embox/unit.h>12#include <hal/clock.h>13#include <hal/system.h>14#include <kernel/irq.h>15#include <kernel/time/clock_source.h>16#include <stdint.h>17
18/** Test for different frequancy (300K ticks -- i.e. 5min)
19* 300MHz is 00:04:10.356 (300K)
20* 333MHz is 00:04:37.672 (300K)
21* 350MHz is 00:05:22.747 (300K)
22* 366MHz is 00:05:39.987 (300K)
23* 375MHz is 00:06:27.322 (343K)
24* We will use 333MHz as default settings
25*/
26#define PPCCLK_IRQ 1027#define PPCCLK_FREQ SYS_CLOCK28#define PPCCLK_DECR (PPCCLK_FREQ / 1000) /* precision for ms */29
30static irq_return_t clock_handler(unsigned int irq_nr, void *data) {31__set_tsr(__get_tsr() & ~TSR_DIS);32clock_tick_handler( data);33return IRQ_HANDLED;34}
35
36static int ppc_clk_set_periodic(struct clock_source *cs) {37__set_dec(PPCCLK_DECR);38__set_decar(PPCCLK_DECR);39__set_tcr(TCR_DIE | TCR_ARE);40return 0;41}
42
43static cycle_t ppc_clk_read(struct clock_source *cs) {44uint32_t l, u, tmp;45tmp = __get_tbu();46do {47u = tmp;48l = __get_tbl();49tmp = __get_tbu();50} while (tmp != u);51return ((uint64_t)u << 32) | l;52}
53
54static struct time_event_device ppc_clk_event = {55.set_periodic = ppc_clk_set_periodic,56.irq_nr = PPCCLK_IRQ,57};58
59static struct time_counter_device ppc_clk_counter = {60.read = ppc_clk_read,61.cycle_hz = PPCCLK_FREQ,62};63
64static int ppc_clk_init(struct clock_source *cs) {65return irq_attach(PPCCLK_IRQ, clock_handler, 0, cs, "ppc_clk");66}
67
68CLOCK_SOURCE_DEF(ppc_clk, ppc_clk_init, NULL,69&ppc_clk_event, &ppc_clk_counter);70