]> xenbits.xensource.com Git - people/aperard/xen-arm.git/commitdiff
arm: exynos5,arndale: start generic timer.
authorAnthony PERARD <anthony.perard@citrix.com>
Tue, 22 Jan 2013 16:29:49 +0000 (16:29 +0000)
committerAnthony PERARD <anthony.perard@citrix.com>
Mon, 28 Jan 2013 15:55:21 +0000 (15:55 +0000)
xen/arch/arm/arm32/mode_switch.S
xen/arch/arm/time.c

index 8add8c01167093a0bffab931cae620a93c0dee73..3af68f76f9b38b65be5daae0ff2a93d223e5b851 100644 (file)
@@ -72,7 +72,7 @@ enter_hyp_mode:
          * programmable in Secure state.  Since we don't know where its
          * memory-mapped control registers live, we can't find out the
          * right frequency.  Use the VE model's default frequency here. */
-        ldr   r0, =0x5f5e100         /* 100 MHz */
+        ldr   r0, =(24*1000*1000)         /* 24 MHz for arndale */
         mcr   CP32(r0, CNTFRQ)
         ldr   r0, =0x40c00           /* SMP, c11, c10 in non-secure mode */
         mcr   CP32(r0, NSACR)
index 07628e1bc3744aafb42c763058e772ed7ef8eb46..f6c381b1a2c529363d2382b80b50e6bda9abb650 100644 (file)
  * instead.
  */
 #define USE_HYP_TIMER 1
+#define IRQ_SPI(x) (x)
+#define EXYNOS5_IRQ_MCT_L0             IRQ_SPI(120)
+#define EXYNOS5_IRQ_MCT_L1             IRQ_SPI(121)
 
+#define MCT_BASE 0x101c0000
+#define EXYNOS4_MCTREG(x)   (MCT_BASE + (x))
+
+#define EXYNOS4_MCT_G_CNT_L            EXYNOS4_MCTREG(0x100)
+#define EXYNOS4_MCT_G_CNT_U            EXYNOS4_MCTREG(0x104)
+#define EXYNOS4_MCT_G_CNT_WSTAT                EXYNOS4_MCTREG(0x110)
+
+#define EXYNOS4_MCT_G_COMP0_L          EXYNOS4_MCTREG(0x200)
+#define EXYNOS4_MCT_G_COMP0_U          EXYNOS4_MCTREG(0x204)
+#define EXYNOS4_MCT_G_COMP0_ADD_INCR   EXYNOS4_MCTREG(0x208)
+
+#define EXYNOS4_MCT_G_TCON             EXYNOS4_MCTREG(0x240)
+
+#define EXYNOS4_MCT_G_INT_CSTAT                EXYNOS4_MCTREG(0x244)
+#define EXYNOS4_MCT_G_INT_ENB          EXYNOS4_MCTREG(0x248)
+#define EXYNOS4_MCT_G_WSTAT            EXYNOS4_MCTREG(0x24C)
+
+#define _EXYNOS4_MCT_L_BASE            EXYNOS4_MCTREG(0x300)
+    // cpu nb
+#define EXYNOS4_MCT_L_BASE(x)          (_EXYNOS4_MCT_L_BASE + (0x100 * x))
+#define EXYNOS4_MCT_L_MASK             (0xffffff00)
+
+#define MCT_L_TCNTB_OFFSET             (0x00)
+#define MCT_L_ICNTB_OFFSET             (0x08)
+#define MCT_L_TCON_OFFSET              (0x20)
+#define MCT_L_INT_CSTAT_OFFSET         (0x30)
+#define MCT_L_INT_ENB_OFFSET           (0x34)
+#define MCT_L_WSTAT_OFFSET             (0x40)
+
+#define MCT_G_TCON_START               (1 << 8)
+#define MCT_G_TCON_COMP0_AUTO_INC      (1 << 1)
+#define MCT_G_TCON_COMP0_ENABLE                (1 << 0)
+
+#define MCT_L_TCON_INTERVAL_MODE       (1 << 2)
+#define MCT_L_TCON_INT_START           (1 << 1)
+#define MCT_L_TCON_TIMER_START         (1 << 0)
 uint64_t __read_mostly boot_count;
 
 /* For fine-grained timekeeping, we use the ARM "Generic Timer", a
@@ -86,13 +125,41 @@ static uint32_t calibrate_timer(void)
 }
 */
 
+uint32_t read_register(uint32_t addr)
+{
+    volatile const uint32_t *reg;
+    uint32_t value;
+    set_fixmap(FIXMAP_MISC, addr >> PAGE_SHIFT, DEV_SHARED);
+    reg = (uint32_t *)(FIXMAP_ADDR(FIXMAP_MISC) + (addr & ~PAGE_MASK));
+    value = *reg;
+    clear_fixmap(FIXMAP_MISC);
+    return value;
+}
+
+void write_register(uint32_t addr, uint32_t value)
+{
+    volatile uint32_t *reg;
+    set_fixmap(FIXMAP_MISC, addr >> PAGE_SHIFT, DEV_SHARED);
+    reg = (uint32_t *)(FIXMAP_ADDR(FIXMAP_MISC) + (addr & ~PAGE_MASK));
+    *reg = value;
+    clear_fixmap(FIXMAP_MISC);
+}
+
 /* Set up the timer on the boot CPU */
 int __init init_xen_time(void)
 {
+    uint32_t reg;
+
     /* Check that this CPU supports the Generic Timer interface */
     if ( (READ_CP32(ID_PFR1) & ID_PFR1_GT_MASK) != ID_PFR1_GT_v1 )
         panic("CPU does not support the Generic Timer v1 interface.\n");
 
+    // enable timer on exynos5 arndale board
+    // should probably be done by u-boot
+    reg = read_register(EXYNOS4_MCT_G_TCON);
+    write_register(EXYNOS4_MCT_G_TCON, reg | MCT_G_TCON_START);
+
+
     cntfrq = READ_CP32(CNTFRQ);
     boot_count = READ_CP64(CNTPCT);
     printk("Using generic timer at %"PRIu32" Hz\n", cntfrq);