board.c 4.7 KB
Newer Older
B
bernard 已提交
1
/*
2
 * Copyright (c) 2006-2021, RT-Thread Development Team
B
bernard 已提交
3
 *
4
 * SPDX-License-Identifier: Apache-2.0
B
bernard 已提交
5 6 7 8 9 10 11 12
 *
 * Change Logs:
 * Date           Author       Notes
 * 2012-11-20     Bernard    the first version
 */

#include <rthw.h>
#include <rtthread.h>
B
Bernard Xiong 已提交
13
#include <finsh.h>
B
bernard 已提交
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

#include "board.h"
#include <interrupt.h>

#ifdef RT_USING_VMM
#include <vmm.h>
static rt_uint32_t DMTIMER = 0;
#define TIMER_HW_BASE (DMTIMER)
#else
#define TIMER_HW_BASE AM33XX_DMTIMER_7_REGS
#endif

#define DMTIMER_TCLR_AR                         (0x00000002u)
#define DMTIMER_TCLR_CE                         (0x00000040u)
#define DMTIMER_TCLR_PRE                        (0x00000020u)
#define DMTIMER_TCLR_ST                         (0x00000001u)
#define DMTIMER_IRQENABLE_SET_OVF_EN_FLAG       (0x00000002u)
#define DMTIMER_IRQSTATUS_RAW_OVF_IT_FLAG       (0x00000002u)

#define CM_DPLL_CLKSEL_CLK_CLKSEL               (0x00000003u)
#define CM_DPLL_CLKSEL_CLK_CLKSEL_SEL3          (0x2u)

#define CM_PER_CLKCTRL_MODULEMODE_ENABLE        (0x2u)
#define CM_PER_CLKCTRL_MODULEMODE               (0x00000003u)

#define CM_PER_CLKCTRL_IDLEST                   (0x00030000u)
#define CM_PER_CLKCTRL_IDLEST_FUNC              (0x0u)

#define CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK     (0x00000100u)
#define CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_TIMER2_GCLK   (0x00004000u)
#define CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_TIMER7_GCLK   (1<<13)

static void rt_hw_timer_isr(int vector, void* param)
{
48
    rt_tick_increase();
B
bernard 已提交
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

    DMTIMER_IRQSTATUS(TIMER_HW_BASE) = DMTIMER_IRQSTATUS_RAW_OVF_IT_FLAG;
}

static void timer_clk_init(void)
{
    unsigned long prcm_base;

#ifdef RT_USING_VMM
    prcm_base = vmm_find_iomap("PRCM");
#else
    prcm_base = AM33XX_PRCM_REGS;
#endif

    /* software forced wakeup */
    CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) |= 0x2;

    /* Waiting for the L4LS clock */
    while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & (1<<8)))
        ;

70 71 72 73
    /* Select the clock source for the Timer2 instance.  */
    CM_DPLL_CLKSEL_TIMER7_CLK(prcm_base) &= ~(CM_DPLL_CLKSEL_CLK_CLKSEL);
    /* 32k clock source */
    CM_DPLL_CLKSEL_TIMER7_CLK(prcm_base) |= CM_DPLL_CLKSEL_CLK_CLKSEL_SEL3;
B
bernard 已提交
74

75 76
    while ((CM_DPLL_CLKSEL_TIMER7_CLK(prcm_base) & CM_DPLL_CLKSEL_CLK_CLKSEL) !=
        CM_DPLL_CLKSEL_CLK_CLKSEL_SEL3);
B
bernard 已提交
77

78 79
    /* Writing to MODULEMODE field of CM_PER_TIMER7_CLKCTRL register. */
    CM_PER_TIMER7_CLKCTRL(prcm_base) |= CM_PER_CLKCTRL_MODULEMODE_ENABLE;
B
bernard 已提交
80

81 82 83
    /* Waiting for MODULEMODE field to reflect the written value. */
    while ((CM_PER_TIMER7_CLKCTRL(prcm_base) & CM_PER_CLKCTRL_MODULEMODE) !=
        CM_PER_CLKCTRL_MODULEMODE_ENABLE);
B
bernard 已提交
84

85 86 87 88 89 90
    /*
     * Waiting for IDLEST field in CM_PER_TIMER7_CLKCTRL register
     * for the module is fully functional.
     */
    while ((CM_PER_TIMER7_CLKCTRL(prcm_base) & CM_PER_CLKCTRL_IDLEST) !=
        CM_PER_CLKCTRL_IDLEST_FUNC);
B
bernard 已提交
91

92 93 94 95
    /* Waiting for the L4LS clock */
    while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK));
    /* Waiting for the TIMER7 clock */
    while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_TIMER7_GCLK));
B
bernard 已提交
96 97 98 99
}

int rt_hw_timer_init(void)
{
100
    rt_uint32_t counter;
B
bernard 已提交
101 102 103 104 105

#ifdef RT_USING_VMM
    DMTIMER = vmm_find_iomap("TIMER7");
#endif

106
    timer_clk_init();
B
bernard 已提交
107

108 109
    /* soft reset the timer */
    DMTIMER_TIOCP_CFG(TIMER_HW_BASE) |= 1;
B
bernard 已提交
110 111 112
    while ((DMTIMER_TIOCP_CFG(TIMER_HW_BASE) & 0x1) == 1)
        ;

113 114
    /* calculate count */
    counter = 0xffffffff - (32768UL/RT_TICK_PER_SECOND);
B
bernard 已提交
115

116 117 118 119
    /* set initial count */
    DMTIMER_TCRR(TIMER_HW_BASE) = counter;
    /* set reload count */
    DMTIMER_TLDR(TIMER_HW_BASE) = counter;
B
bernard 已提交
120

121 122
    /* set mode: auto reload */
    DMTIMER_TCLR(TIMER_HW_BASE) |= DMTIMER_TCLR_AR;
B
bernard 已提交
123

124 125
    /* interrupt enable for match */
    DMTIMER_IRQENABLE_SET(TIMER_HW_BASE) = DMTIMER_IRQENABLE_SET_OVF_EN_FLAG;
B
bernard 已提交
126 127
    DMTIMER_IRQSTATUS(TIMER_HW_BASE) = DMTIMER_IRQSTATUS_RAW_OVF_IT_FLAG;

128 129 130
    rt_hw_interrupt_install(TINT7, rt_hw_timer_isr, RT_NULL, "tick");
    rt_hw_interrupt_control(TINT7, 0, 0);
    rt_hw_interrupt_umask(TINT7);
B
bernard 已提交
131 132 133 134

    while (DMTIMER_TWPS(TIMER_HW_BASE) != 0)
        ;

135 136
    /* start timer */
    DMTIMER_TCLR(TIMER_HW_BASE) |= DMTIMER_TCLR_ST;
B
bernard 已提交
137 138 139 140 141 142 143 144 145 146 147 148 149 150

    while (DMTIMER_TWPS(TIMER_HW_BASE) != 0)
        ;

    return 0;
}
INIT_BOARD_EXPORT(rt_hw_timer_init);

/**
 * This function will initialize beaglebone board
 */
void rt_hw_board_init(void)
{
    rt_components_board_init();
151
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
B
bernard 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165
}

void rt_hw_cpu_reset(void)
{
    unsigned long prcm_base;

#ifdef RT_USING_VMM
    prcm_base = vmm_find_iomap("PRCM");
#else
    prcm_base = AM33XX_PRCM_REGS;
#endif
    REG32(PRM_DEVICE(prcm_base)) = 0x1;
    RT_ASSERT(0);
}
166
MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reboot the cpu);