1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/*
* arc-timer.c -- provide API for ARC timers.
*
* Copyright (c) 2024 Synopsys Inc.
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*
*/
#include "arc-specific.h"
#define ARC_TIM_BUILD 0x75
#define ARC_TIM_BUILD_VER_MASK 0x00FF
#define ARC_TIM_BUILD_TIM0_FL 0x0100
#define ARC_TIM_BUILD_TIM1_FL 0x0200
#define ARC_TIM_COUNT0 0x21
#define ARC_TIM_CONTROL0 0x22
#define ARC_TIM_LIMIT0 0x23
#define ARC_TIM_COUNT1 0x100
#define ARC_TIM_CONTROL1 0x101
#define ARC_TIM_LIMIT1 0x102
#define ARC_TIM_CONTROL_NH_FL 0x0002
/* Timer used by '_default' functions. */
const unsigned int arc_timer_default = 0;
/* Check if given timer exists. */
static int
_arc_timer_present (unsigned int tim)
{
unsigned int bcr = read_aux_reg (ARC_TIM_BUILD);
unsigned int ver = bcr & ARC_TIM_BUILD_VER_MASK;
if (ver == 0)
return 0;
else if (ver == 1)
return 1;
else if (tim == 0)
return ((bcr & ARC_TIM_BUILD_TIM0_FL) != 0);
else if (tim == 1)
return ((bcr & ARC_TIM_BUILD_TIM1_FL) != 0);
else
return 0;
}
/* Get raw value of a given timer. */
static unsigned int
_arc_timer_read (unsigned int tim)
{
if (_arc_timer_present (tim))
{
if (tim == 0)
return read_aux_reg (ARC_TIM_COUNT0);
else if (tim == 1)
return read_aux_reg (ARC_TIM_COUNT1);
}
return 0;
}
/*
* Set default values to a given timer.
* Defaults: Not Halted bit is set, limit is 0xFFFFFFFF, count set to 0.
*/
static void
_arc_timer_reset (unsigned int tim)
{
unsigned int ctrl, tim_control, tim_count, tim_limit;
if (_arc_timer_present (tim))
{
if (tim == 0)
{
tim_control = ARC_TIM_CONTROL0;
tim_count = ARC_TIM_COUNT0;
tim_limit = ARC_TIM_LIMIT0;
}
else if (tim == 1)
{
tim_control = ARC_TIM_CONTROL1;
tim_count = ARC_TIM_COUNT1;
tim_limit = ARC_TIM_LIMIT1;
}
else
{
return;
}
ctrl = read_aux_reg (tim_control);
/* Disable timer interrupt when programming. */
write_aux_reg (0, tim_control);
/* Default limit is 24-bit, increase it to 32-bit. */
write_aux_reg (0xFFFFFFFF, tim_limit);
/* Set NH bit to count only when processor is running. */
write_aux_reg (ctrl | ARC_TIM_CONTROL_NH_FL, tim_control);
write_aux_reg (0, tim_count);
}
}
/* Check if arc_timer_default exists. */
int
_arc_timer_default_present (void)
{
return _arc_timer_present (arc_timer_default);
}
/* Read arc_timer_default value. */
unsigned int
_arc_timer_default_read (void)
{
return _arc_timer_read (arc_timer_default);
}
/* Reset arc_timer_default. */
void
_arc_timer_default_reset (void)
{
_arc_timer_reset (arc_timer_default);
}
|