summaryrefslogtreecommitdiff
path: root/bsp/beaglebone/applications/board.c
blob: ae110fb57feec41036712eb27bf87eeba700c531 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2012-11-20     Bernard    the first version
 */

#include <rthw.h>
#include <rtthread.h>
#include <finsh.h>

#include "board.h"
#include <mmu.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)
{
    rt_tick_increase();

    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)))
        ;

    /* 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;

    while ((CM_DPLL_CLKSEL_TIMER7_CLK(prcm_base) & CM_DPLL_CLKSEL_CLK_CLKSEL) !=
        CM_DPLL_CLKSEL_CLK_CLKSEL_SEL3);

    /* Writing to MODULEMODE field of CM_PER_TIMER7_CLKCTRL register. */
    CM_PER_TIMER7_CLKCTRL(prcm_base) |= CM_PER_CLKCTRL_MODULEMODE_ENABLE;

    /* 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);

    /*
     * 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);

    /* 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));
}

int rt_hw_timer_init(void)
{
    rt_uint32_t counter;

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

    timer_clk_init();

    /* soft reset the timer */
    DMTIMER_TIOCP_CFG(TIMER_HW_BASE) |= 1;
    while ((DMTIMER_TIOCP_CFG(TIMER_HW_BASE) & 0x1) == 1)
        ;

    /* calculate count */
    counter = 0xffffffff - (32768UL/RT_TICK_PER_SECOND);

    /* set initial count */
    DMTIMER_TCRR(TIMER_HW_BASE) = counter;
    /* set reload count */
    DMTIMER_TLDR(TIMER_HW_BASE) = counter;

    /* set mode: auto reload */
    DMTIMER_TCLR(TIMER_HW_BASE) |= DMTIMER_TCLR_AR;

    /* interrupt enable for match */
    DMTIMER_IRQENABLE_SET(TIMER_HW_BASE) = DMTIMER_IRQENABLE_SET_OVF_EN_FLAG;
    DMTIMER_IRQSTATUS(TIMER_HW_BASE) = DMTIMER_IRQSTATUS_RAW_OVF_IT_FLAG;

    rt_hw_interrupt_install(TINT7, rt_hw_timer_isr, RT_NULL, "tick");
    rt_hw_interrupt_control(TINT7, 0, 0);
    rt_hw_interrupt_umask(TINT7);

    while (DMTIMER_TWPS(TIMER_HW_BASE) != 0)
        ;

    /* start timer */
    DMTIMER_TCLR(TIMER_HW_BASE) |= DMTIMER_TCLR_ST;

    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_hw_mmu_init();

    /* init hardware interrupt */
    rt_hw_interrupt_init();

    /* Heap initialization */
#if defined(RT_USING_HEAP)
    rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif

    rt_components_board_init();
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
}

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);
}
MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reboot the cpu);