case ARCH_TIMER_REG_CTRL:
                        asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
                        break;
-               case ARCH_TIMER_REG_TVAL:
-                       asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" ((u32)val));
+               case ARCH_TIMER_REG_CVAL:
+                       asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
                        break;
                default:
                        BUILD_BUG();
                case ARCH_TIMER_REG_CTRL:
                        asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
                        break;
-               case ARCH_TIMER_REG_TVAL:
-                       asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" ((u32)val));
+               case ARCH_TIMER_REG_CVAL:
+                       asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val));
                        break;
                default:
                        BUILD_BUG();
 
                case ARCH_TIMER_REG_CTRL:
                        write_sysreg(val, cntp_ctl_el0);
                        break;
-               case ARCH_TIMER_REG_TVAL:
-                       write_sysreg(val, cntp_tval_el0);
+               case ARCH_TIMER_REG_CVAL:
+                       write_sysreg(val, cntp_cval_el0);
                        break;
                default:
                        BUILD_BUG();
                case ARCH_TIMER_REG_CTRL:
                        write_sysreg(val, cntv_ctl_el0);
                        break;
-               case ARCH_TIMER_REG_TVAL:
-                       write_sysreg(val, cntv_tval_el0);
+               case ARCH_TIMER_REG_CVAL:
+                       write_sysreg(val, cntv_cval_el0);
                        break;
                default:
                        BUILD_BUG();
 }
 
 static __always_inline
-u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
+u64 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 {
        if (access == ARCH_TIMER_PHYS_ACCESS) {
                switch (reg) {
 
                                           struct clock_event_device *clk)
 {
        unsigned long ctrl;
+       u64 cnt;
+
        ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
        ctrl |= ARCH_TIMER_CTRL_ENABLE;
        ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
-       arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
+
+       if (access == ARCH_TIMER_PHYS_ACCESS)
+               cnt = __arch_counter_get_cntpct();
+       else
+               cnt = __arch_counter_get_cntvct();
+
+       arch_timer_reg_write(access, ARCH_TIMER_REG_CVAL, evt + cnt, clk);
        arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
 }
 
        return 0;
 }
 
+static __always_inline void set_next_event_mem(const int access, unsigned long evt,
+                                          struct clock_event_device *clk)
+{
+       unsigned long ctrl;
+       ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
+       ctrl |= ARCH_TIMER_CTRL_ENABLE;
+       ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
+
+       arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
+       arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
+}
+
 static int arch_timer_set_next_event_virt_mem(unsigned long evt,
                                              struct clock_event_device *clk)
 {
-       set_next_event(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
+       set_next_event_mem(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
        return 0;
 }
 
 static int arch_timer_set_next_event_phys_mem(unsigned long evt,
                                              struct clock_event_device *clk)
 {
-       set_next_event(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
+       set_next_event_mem(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
        return 0;
 }