44
44
#define CNTACR_RWVT BIT(4)
45
45
#define CNTACR_RWPT BIT(5)
46
46
47
- #define CNTVCT_LO 0x08
48
- #define CNTVCT_HI 0x0c
47
+ #define CNTVCT_LO 0x00
48
+ #define CNTPCT_LO 0x08
49
49
#define CNTFRQ 0x10
50
+ #define CNTP_CVAL_LO 0x20
50
51
#define CNTP_TVAL 0x28
51
52
#define CNTP_CTL 0x2c
53
+ #define CNTV_CVAL_LO 0x30
52
54
#define CNTV_TVAL 0x38
53
55
#define CNTV_CTL 0x3c
54
56
@@ -112,6 +114,13 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
112
114
case ARCH_TIMER_REG_TVAL :
113
115
writel_relaxed ((u32 )val , timer -> base + CNTP_TVAL );
114
116
break ;
117
+ case ARCH_TIMER_REG_CVAL :
118
+ /*
119
+ * Not guaranteed to be atomic, so the timer
120
+ * must be disabled at this point.
121
+ */
122
+ writeq_relaxed (val , timer -> base + CNTP_CVAL_LO );
123
+ break ;
115
124
default :
116
125
BUILD_BUG ();
117
126
}
@@ -124,6 +133,10 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
124
133
case ARCH_TIMER_REG_TVAL :
125
134
writel_relaxed ((u32 )val , timer -> base + CNTV_TVAL );
126
135
break ;
136
+ case ARCH_TIMER_REG_CVAL :
137
+ /* Same restriction as above */
138
+ writeq_relaxed (val , timer -> base + CNTV_CVAL_LO );
139
+ break ;
127
140
default :
128
141
BUILD_BUG ();
129
142
}
@@ -720,15 +733,36 @@ static int arch_timer_set_next_event_phys(unsigned long evt,
720
733
return 0 ;
721
734
}
722
735
736
+ static u64 arch_counter_get_cnt_mem (struct arch_timer * t , int offset_lo )
737
+ {
738
+ u32 cnt_lo , cnt_hi , tmp_hi ;
739
+
740
+ do {
741
+ cnt_hi = readl_relaxed (t -> base + offset_lo + 4 );
742
+ cnt_lo = readl_relaxed (t -> base + offset_lo );
743
+ tmp_hi = readl_relaxed (t -> base + offset_lo + 4 );
744
+ } while (cnt_hi != tmp_hi );
745
+
746
+ return ((u64 ) cnt_hi << 32 ) | cnt_lo ;
747
+ }
748
+
723
749
static __always_inline void set_next_event_mem (const int access , unsigned long evt ,
724
750
struct clock_event_device * clk )
725
751
{
752
+ struct arch_timer * timer = to_arch_timer (clk );
726
753
unsigned long ctrl ;
754
+ u64 cnt ;
755
+
727
756
ctrl = arch_timer_reg_read (access , ARCH_TIMER_REG_CTRL , clk );
728
757
ctrl |= ARCH_TIMER_CTRL_ENABLE ;
729
758
ctrl &= ~ARCH_TIMER_CTRL_IT_MASK ;
730
759
731
- arch_timer_reg_write (access , ARCH_TIMER_REG_TVAL , evt , clk );
760
+ if (access == ARCH_TIMER_MEM_VIRT_ACCESS )
761
+ cnt = arch_counter_get_cnt_mem (timer , CNTVCT_LO );
762
+ else
763
+ cnt = arch_counter_get_cnt_mem (timer , CNTPCT_LO );
764
+
765
+ arch_timer_reg_write (access , ARCH_TIMER_REG_CVAL , evt + cnt , clk );
732
766
arch_timer_reg_write (access , ARCH_TIMER_REG_CTRL , ctrl , clk );
733
767
}
734
768
@@ -970,15 +1004,7 @@ bool arch_timer_evtstrm_available(void)
970
1004
971
1005
static u64 arch_counter_get_cntvct_mem (void )
972
1006
{
973
- u32 vct_lo , vct_hi , tmp_hi ;
974
-
975
- do {
976
- vct_hi = readl_relaxed (arch_timer_mem -> base + CNTVCT_HI );
977
- vct_lo = readl_relaxed (arch_timer_mem -> base + CNTVCT_LO );
978
- tmp_hi = readl_relaxed (arch_timer_mem -> base + CNTVCT_HI );
979
- } while (vct_hi != tmp_hi );
980
-
981
- return ((u64 ) vct_hi << 32 ) | vct_lo ;
1007
+ return arch_counter_get_cnt_mem (arch_timer_mem , CNTVCT_LO );
982
1008
}
983
1009
984
1010
static struct arch_timer_kvm_info arch_timer_kvm_info ;
0 commit comments