Ejemplo n.º 1
0
Archivo: omap5.c Proyecto: CPFL/xen
/*
 * The realtime counter also called master counter, is a free-running
 * counter, which is related to real time. It produces the count used
 * by the CPU local timer peripherals in the MPU cluster. The timer counts
 * at a rate of 6.144 MHz. Because the device operates on different clocks
 * in different power modes, the master counter shifts operation between
 * clocks, adjusting the increment per clock in hardware accordingly to
 * maintain a constant count rate.
 */
static int omap5_init_time(void)
{
    void __iomem *ckgen_prm_base;
    void __iomem *rt_ct_base;
    unsigned int sys_clksel;
    unsigned int num, den, frac1, frac2;

    ckgen_prm_base = ioremap_attr(OMAP5_CKGEN_PRM_BASE,
                                  0x20, PAGE_HYPERVISOR_NOCACHE);
    if ( !ckgen_prm_base )
    {
        dprintk(XENLOG_ERR, "%s: PRM_BASE ioremap failed\n", __func__);
        return -ENOMEM;
    }

    sys_clksel = readl(ckgen_prm_base + OMAP5_CM_CLKSEL_SYS) &
        ~SYS_CLKSEL_MASK;

    iounmap(ckgen_prm_base);

    rt_ct_base = ioremap_attr(REALTIME_COUNTER_BASE,
                              0x20, PAGE_HYPERVISOR_NOCACHE);
    if ( !rt_ct_base )
    {
        dprintk(XENLOG_ERR, "%s: REALTIME_COUNTER_BASE ioremap failed\n", __func__);
        return -ENOMEM;
    }

    frac1 = readl(rt_ct_base + INCREMENTER_NUMERATOR_OFFSET);
    num = frac1 & ~NUMERATOR_DENUMERATOR_MASK;
    if ( num_den[sys_clksel][0] != num )
    {
        frac1 &= NUMERATOR_DENUMERATOR_MASK;
        frac1 |= num_den[sys_clksel][0];
    }

    frac2 = readl(rt_ct_base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
    den = frac2 & ~NUMERATOR_DENUMERATOR_MASK;
    if ( num_den[sys_clksel][1] != num )
    {
        frac2 &= NUMERATOR_DENUMERATOR_MASK;
        frac2 |= num_den[sys_clksel][1];
    }

    writel(frac1, rt_ct_base + INCREMENTER_NUMERATOR_OFFSET);
    writel(frac2 | PRM_FRAC_INCREMENTER_DENUMERATOR_RELOAD,
           rt_ct_base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);

    iounmap(rt_ct_base);

    return 0;
}
Ejemplo n.º 2
0
Archivo: exynos5.c Proyecto: CPFL/xen
static int exynos5_init_time(void)
{
    uint32_t reg;
    void __iomem *mct;
    int rc;
    struct dt_device_node *node;
    u64 mct_base_addr;
    u64 size;

    node = dt_find_compatible_node(NULL, NULL, "samsung,exynos4210-mct");
    if ( !node )
    {
        dprintk(XENLOG_ERR, "samsung,exynos4210-mct missing in DT\n");
        return -ENXIO;
    }

    rc = dt_device_get_address(node, 0, &mct_base_addr, &size);
    if ( rc )
    {
        dprintk(XENLOG_ERR, "Error in \"samsung,exynos4210-mct\"\n");
        return -ENXIO;
    }

    dprintk(XENLOG_INFO, "mct_base_addr: %016llx size: %016llx\n",
            mct_base_addr, size);

    mct = ioremap_attr(mct_base_addr, size, PAGE_HYPERVISOR_NOCACHE);
    if ( !mct )
    {
        dprintk(XENLOG_ERR, "Unable to map MCT\n");
        return -ENOMEM;
    }

    /* Enable timer on Exynos 5250 should probably be done by u-boot */
    reg = readl(mct + EXYNOS5_MCT_G_TCON);
    writel(reg | EXYNOS5_MCT_G_TCON_START, mct + EXYNOS5_MCT_G_TCON);

    iounmap(mct);

    return 0;
}
Ejemplo n.º 3
0
static int exynos5_init_time(void)
{
    uint32_t reg;
    void __iomem *mct;

    BUILD_BUG_ON(EXYNOS5_MCT_G_TCON >= PAGE_SIZE);

    mct = ioremap_attr(EXYNOS5_MCT_BASE, PAGE_SIZE, PAGE_HYPERVISOR_NOCACHE);
    if ( !mct )
    {
        dprintk(XENLOG_ERR, "Unable to map MCT\n");
        return -ENOMEM;
    }

    /* Enable timer on Exynos 5250 should probably be done by u-boot */
    reg = readl(mct + EXYNOS5_MCT_G_TCON);
    writel(reg | EXYNOS5_MCT_G_TCON_START, mct + EXYNOS5_MCT_G_TCON);

    iounmap(mct);

    return 0;
}