blob: 3f6a3ea833c6317c8de9f0f2a28d427eaf1cb995 [file] [log] [blame]
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +01001/*
2 * Copyright (c) 2018 - 2019 Antmicro <www.antmicro.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
Kumar Gala88469b72020-03-24 15:58:31 -05007#define DT_DRV_COMPAT litex_timer0
8
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +01009#include <kernel.h>
10#include <arch/cpu.h>
11#include <device.h>
12#include <irq.h>
Jakub Cebulski265d2cf2020-05-18 17:32:22 +020013#include <spinlock.h>
Anas Nashif68c389c2019-06-21 12:55:37 -040014#include <drivers/timer/system_timer.h>
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010015
Kumar Gala88469b72020-03-24 15:58:31 -050016#define TIMER_BASE DT_INST_REG_ADDR(0)
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010017#define TIMER_LOAD_ADDR ((TIMER_BASE) + 0x00)
18#define TIMER_RELOAD_ADDR ((TIMER_BASE) + 0x10)
19#define TIMER_EN_ADDR ((TIMER_BASE) + 0x20)
20#define TIMER_EV_PENDING_ADDR ((TIMER_BASE) + 0x3c)
21#define TIMER_EV_ENABLE_ADDR ((TIMER_BASE) + 0x40)
Jakub Cebulski265d2cf2020-05-18 17:32:22 +020022#define TIMER_TOTAL_UPDATE ((TIMER_BASE) + 0x44)
23#define TIMER_TOTAL ((TIMER_BASE) + 0x48)
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010024
25#define TIMER_EV 0x1
Kumar Gala88469b72020-03-24 15:58:31 -050026#define TIMER_IRQ DT_INST_IRQN(0)
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010027#define TIMER_DISABLE 0x0
28#define TIMER_ENABLE 0x1
Jakub Cebulski265d2cf2020-05-18 17:32:22 +020029#define UPDATE_TOTAL 0x1
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010030
Tomasz Bursztyka4dcfb552020-06-17 14:58:56 +020031static void litex_timer_irq_handler(const void *device)
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010032{
33 ARG_UNUSED(device);
34 int key = irq_lock();
35
36 sys_write8(TIMER_EV, TIMER_EV_PENDING_ADDR);
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010037 z_clock_announce(1);
38
39 irq_unlock(key);
40}
41
Kumar Galaa1b77fd2020-05-27 11:26:57 -050042uint32_t z_timer_cycle_get_32(void)
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010043{
Jakub Cebulski265d2cf2020-05-18 17:32:22 +020044 static struct k_spinlock lock;
Kumar Galaa1b77fd2020-05-27 11:26:57 -050045 uint32_t timer_total;
Jakub Cebulski265d2cf2020-05-18 17:32:22 +020046 k_spinlock_key_t key = k_spin_lock(&lock);
47
48 litex_write8(UPDATE_TOTAL, TIMER_TOTAL_UPDATE);
Kumar Galaa1b77fd2020-05-27 11:26:57 -050049 timer_total = (uint32_t)litex_read64(TIMER_TOTAL);
Jakub Cebulski265d2cf2020-05-18 17:32:22 +020050
51 k_spin_unlock(&lock, key);
52
53 return timer_total;
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010054}
55
56/* tickless kernel is not supported */
Kumar Galaa1b77fd2020-05-27 11:26:57 -050057uint32_t z_clock_elapsed(void)
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010058{
59 return 0;
60}
61
Tomasz Bursztykae18fcbb2020-04-30 20:33:38 +020062int z_clock_driver_init(const struct device *device)
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010063{
64 ARG_UNUSED(device);
Kumar Gala88469b72020-03-24 15:58:31 -050065 IRQ_CONNECT(TIMER_IRQ, DT_INST_IRQ(0, priority),
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010066 litex_timer_irq_handler, NULL, 0);
67 irq_enable(TIMER_IRQ);
68
69 sys_write8(TIMER_DISABLE, TIMER_EN_ADDR);
70
71 for (int i = 0; i < 4; i++) {
Andy Ross88924062019-10-03 11:43:10 -070072 sys_write8(k_ticks_to_cyc_floor32(1) >> (24 - i * 8),
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010073 TIMER_RELOAD_ADDR + i * 0x4);
Andy Ross88924062019-10-03 11:43:10 -070074 sys_write8(k_ticks_to_cyc_floor32(1) >> (24 - i * 8),
Filip Kokosinskic0c3cdf2019-03-28 14:40:03 +010075 TIMER_LOAD_ADDR + i * 0x4);
76 }
77
78 sys_write8(TIMER_ENABLE, TIMER_EN_ADDR);
79 sys_write8(sys_read8(TIMER_EV_PENDING_ADDR), TIMER_EV_PENDING_ADDR);
80 sys_write8(TIMER_EV, TIMER_EV_ENABLE_ADDR);
81
82 return 0;
83}