Changeset cdfed94f in rtems


Ignore:
Timestamp:
Jun 25, 2018, 9:12:24 AM (11 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
ff7b104
Parents:
1232cd46
git-author:
Sebastian Huber <sebastian.huber@…> (06/25/18 09:12:24)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/28/18 13:03:19)
Message:

bsp/riscv: Rework clock driver

Use device tree provided timebase frequency. Do not write to read-only
mtime register.

Update #3433.

Location:
bsps
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • bsps/include/bsp/fatal.h

    r1232cd46 rcdfed94f  
    11/*
    2  * Copyright (c) 2012, 2016 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2012, 2018 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    138138
    139139  /* i.MX fatal codes */
    140   IMX_FATAL_GENERIC_TIMER_FREQUENCY = BSP_FATAL_CODE_BLOCK(12)
     140  IMX_FATAL_GENERIC_TIMER_FREQUENCY = BSP_FATAL_CODE_BLOCK(12),
     141
     142  /* RISC-V fatal codes */
     143  RISCV_FATAL_NO_TIMEBASE_FREQUENCY_IN_DEVICE_TREE = BSP_FATAL_CODE_BLOCK(13)
    141144} bsp_fatal_code;
    142145
  • bsps/riscv/riscv/clock/clockdrv.c

    r1232cd46 rcdfed94f  
    88
    99/*
    10  * riscv_generic Clock driver
    11  *
     10 * Copyright (c) 2018 embedded brains GmbH
    1211 * COPYRIGHT (c) 2015 Hesham Alatary <hesham@alumni.york.ac.uk>
    1312 *
     
    3433 */
    3534
    36 #include <rtems.h>
    37 #include <bsp.h>
    38 #include <bsp/irq.h>
    39 #include <rtems/score/riscv-utility.h>
    40 #include <rtems/score/cpu.h>
    4135#include <rtems/timecounter.h>
    4236
    43 /* The number of clock cycles before generating a tick timer interrupt. */
    44 #define TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT     1000
    45 #define RISCV_CLOCK_CYCLE_TIME_NANOSECONDS    1
     37#include <bsp.h>
     38#include <bsp/fatal.h>
     39#include <bsp/fdt.h>
     40#include <bsp/irq.h>
    4641
    47 static struct timecounter riscv_generic_tc;
     42#include <dev/irq/clint.h>
    4843
    49 /* CPU counter */
    50 static CPU_Counter_ticks cpu_counter_ticks;
     44#include <libfdt.h>
    5145
    52 /* This prototype is added here to Avoid warnings */
     46#define CLINT ((volatile clint_regs *) 0x02000000)
     47
     48/* This is defined in dev/clock/clockimpl.h */
    5349void Clock_isr(void *arg);
    5450
    55 static void riscv_generic_clock_at_tick(void)
     51static struct timecounter riscv_clock_tc;
     52
     53static uint32_t riscv_clock_interval;
     54
     55static void riscv_clock_at_tick(void)
    5656{
    57   REG(MTIME_MM) = 0;
    58   REG(MTIMECMP_MM) = TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT;
     57  volatile clint_regs *clint;
     58  uint64_t cmp;
    5959
    60   cpu_counter_ticks += TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT * 10000;
     60  clint = CLINT;
     61
     62  cmp = clint->mtimecmp[0].val_64;
     63  cmp += riscv_clock_interval;
     64
     65#if __riscv_xlen == 32
     66  clint->mtimecmp[0].val_32[0] = 0xffffffff;
     67  clint->mtimecmp[0].val_32[1] = (uint32_t) (cmp >> 32);
     68  clint->mtimecmp[0].val_32[0] = (uint32_t) cmp;
     69#elif __riscv_xlen == 64
     70  clint->mtimecmp[0].val_64 = cmp;
     71#endif
    6172}
    6273
    63 static void riscv_generic_clock_handler_install(proc_ptr new_isr)
     74static void riscv_clock_handler_install(proc_ptr new_isr)
    6475{
    65   rtems_status_code sc = RTEMS_SUCCESSFUL;
    6676  _CPU_ISR_install_vector(RISCV_MACHINE_TIMER_INTERRUPT,
    6777                          new_isr,
    6878                          NULL);
    69 
    70   if (sc != RTEMS_SUCCESSFUL) {
    71     rtems_fatal_error_occurred(0xdeadbeef);
    72   }
    7379}
    7480
    75 static uint32_t riscv_generic_get_timecount(struct timecounter *tc)
     81static uint32_t riscv_clock_get_timecount(struct timecounter *tc)
    7682{
    77   uint32_t ticks_since_last_timer_interrupt = REG(MTIME_MM);
     83  volatile clint_regs *clint;
    7884
    79   return cpu_counter_ticks + ticks_since_last_timer_interrupt;
     85  clint = CLINT;
     86  return clint->mtime.val_32[0];
    8087}
    8188
    8289CPU_Counter_ticks _CPU_Counter_read(void)
    8390{
    84   return riscv_generic_get_timecount(NULL);
     91  return riscv_clock_get_timecount(NULL);
    8592}
    8693
    87 static void riscv_generic_clock_initialize(void)
     94static uint32_t riscv_clock_get_timebase_frequency(const void *fdt)
    8895{
    89   uint32_t mtimecmp = TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT;
    90   uint64_t frequency = (1000000000 / RISCV_CLOCK_CYCLE_TIME_NANOSECONDS);
     96  int node;
     97  const uint32_t *val;
     98  int len;
    9199
    92   REG(MTIME_MM) = 0;
    93   REG(MTIMECMP_MM) = TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT;
     100  node = fdt_path_offset(fdt, "/cpus");
     101  val = fdt_getprop(fdt, node, "timebase-frequency", &len);
     102  if (val == NULL || len < 4) {
     103    bsp_fatal(RISCV_FATAL_NO_TIMEBASE_FREQUENCY_IN_DEVICE_TREE);
     104  }
     105
     106  return fdt32_to_cpu(*val);
     107}
     108
     109static void riscv_clock_initialize(void)
     110{
     111  const char *fdt;
     112  uint32_t tb_freq;
     113  uint64_t us_per_tick;
     114
     115  fdt = bsp_fdt_get();
     116  tb_freq = riscv_clock_get_timebase_frequency(fdt);
     117  us_per_tick = rtems_configuration_get_microseconds_per_tick();
     118  riscv_clock_interval = (uint32_t) ((tb_freq * us_per_tick) / 1000000);
     119
     120  riscv_clock_at_tick();
    94121
    95122  /* Enable mtimer interrupts */
    96123  set_csr(mie, MIP_MTIP);
    97   set_csr(mip, MIP_MTIP);
    98124
    99125  /* Initialize timecounter */
    100   riscv_generic_tc.tc_get_timecount = riscv_generic_get_timecount;
    101   riscv_generic_tc.tc_counter_mask = 0xffffffff;
    102   riscv_generic_tc.tc_frequency = frequency;
    103   riscv_generic_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
    104   rtems_timecounter_install(&riscv_generic_tc);
     126  riscv_clock_tc.tc_get_timecount = riscv_clock_get_timecount;
     127  riscv_clock_tc.tc_counter_mask = 0xffffffff;
     128  riscv_clock_tc.tc_frequency = tb_freq;
     129  riscv_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
     130  rtems_timecounter_install(&riscv_clock_tc);
    105131}
    106132
     
    113139}
    114140
    115 #define Clock_driver_support_at_tick() riscv_generic_clock_at_tick()
     141#define Clock_driver_support_at_tick() riscv_clock_at_tick()
    116142
    117 #define Clock_driver_support_initialize_hardware() riscv_generic_clock_initialize()
     143#define Clock_driver_support_initialize_hardware() riscv_clock_initialize()
    118144
    119145#define Clock_driver_support_install_isr(isr) \
    120   riscv_generic_clock_handler_install(isr)
     146  riscv_clock_handler_install(isr)
    121147
    122148#include "../../../shared/dev/clock/clockimpl.h"
  • bsps/riscv/riscv/include/bsp.h

    r1232cd46 rcdfed94f  
    4747#define BSP_FDT_IS_SUPPORTED
    4848
    49 /**
    50   * @defgroup riscv_generic Register Definitions
    51   *
    52   * @ingroup riscv_generic
    53   *
    54   * @brief Shared register definitions for RISC-V systems.
    55   *
    56   * @{
    57   */
    58 
    59 /**
    60   * @name Register Macros
    61   *
    62   * @{
    63   */
    64 
    65 #define REG(x)           (*((volatile unsigned long *) (x)))
    66 #define BIT(n)           (1 << (n))
    67 
    68 #define MTIME_MM    0x000000000200bff8
    69 #define MTIMECMP_MM 0x0000000002004000
    70 
    7149#ifdef __cplusplus
    7250}
Note: See TracChangeset for help on using the changeset viewer.