File size: 3,552 Bytes
829b19c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
/*
 * HAL — OMAP3530 Clock and Power initialization
 */

#include "clock.h"

int clock_init(void) {
    hw_reg32_t cm = (hw_reg32_t)CM_BASE;
    hw_reg32_t prm = (hw_reg32_t)PRM_BASE;

    /* Wait for power sequencing to complete (from power-tree.json) */
    power_seq_wait();

    /* ---- Configure DPLL1 (MPU / CPU) ---- */
    /* Target: 600MHz from 26MHz ref → M=23, N=1 (26×23/1 = 598MHz, ~600) */
    /* DPLL registers are at CM_CLKSEL_DPLL_MPU etc. — simplified for bring-up */

    /* Enable DPLL1 in lock mode — already configured by ROM boot, verify */
    /* On OMAP3530, the ROM bootloader typically leaves DPLL1 at 500MHz.
       We reconfigure for 600MHz. */

    /* DPLL1 M/N values: M = 23, N = 1 → 598 MHz */
    /* CM_CLKSEL1_PLL_MPU offset — OMAP3530-specific */
    reg32_t cm_clksel1_mpu = cm + 0x940;
    reg_mask32(cm_clksel1_mpu, 0x0007FF0F, (23 << 8) | 1);

    /* Wait for DPLL1 to lock (typical <50µs) */
    delay_cycles(50000);

    /* ---- Configure DPLL3 (CORE / peripheral) ---- */
    /* DPLL3 drives L3 interconnect and peripheral clocks.
       Leave at ROM-default for bring-up (usually 166MHz L3). */

    /* ---- Configure DPLL4 (PER / display) ---- */
    /* DPLL4 generates display and peripheral clocks.
       Leave at ROM-default for bring-up. */

    /* ---- Configure DPLL5 (DDR) ---- */
    /* Target: 266MHz DDR clock → M=10, N=1 (26×10/1 = 260MHz) */
    /* DDR2 DPLL — OMAP3530-specific */
    reg32_t cm_clksel5_pll = cm + 0x0F4;
    reg_mask32(cm_clksel5_pll, 0x0007FF0F, (10 << 8) | 1);
    delay_cycles(50000);

    return 0;
}

void clock_enable_uart(void) {
    hw_reg32_t cm = (hw_reg32_t)CM_BASE;

    /* Enable UART1/2 functional and interface clocks */
    reg_set32(cm + CM_FCLKEN1_CORE, (1 << 21) | (1 << 22));  /* UART1, UART2 */
    reg_set32(cm + CM_ICLKEN1_CORE, (1 << 21) | (1 << 22));

    /* Wait for clocks to become active */
    delay_cycles(500);
    while (!(reg_read32(cm + CM_IDLEST1_CORE) & ((1 << 21) | (1 << 22))))
        ;
}

void clock_enable_gpio(void) {
    hw_reg32_t cm = (hw_reg32_t)CM_BASE;

    /* GPIO clocks are in WKUP domain */
    reg_set32(cm + CM_FCLKEN_WKUP, (1 << 4));   /* GPIO1 */
    reg_set32(cm + CM_ICLKEN_WKUP, (1 << 4));

    delay_cycles(500);
}

void clock_enable_gptimer(void) {
    hw_reg32_t cm = (hw_reg32_t)CM_BASE;

    /* GP Timer 1 is in WKUP domain */
    reg_set32(cm + CM_FCLKEN_WKUP, (1 << 2));
    reg_set32(cm + CM_ICLKEN_WKUP, (1 << 2));

    /* GP Timer 2-9 are in PER domain */
    reg32_t cm_fclken_per = cm + 0x500;
    reg32_t cm_iclken_per = cm + 0x510;
    reg_set32(cm_fclken_per, 0x03FF);  /* Timers 2-9 */
    reg_set32(cm_iclken_per, 0x03FF);

    delay_cycles(500);
}

void clock_enable_gpmc(void) {
    hw_reg32_t cm = (hw_reg32_t)CM_BASE;

    /* GPMC functional + interface clocks */
    reg_set32(cm + CM_FCLKEN1_CORE, (1 << 1));
    reg_set32(cm + CM_ICLKEN1_CORE, (1 << 1));

    delay_cycles(500);
    while (!(reg_read32(cm + CM_IDLEST1_CORE) & (1 << 1)))
        ;
}

void clock_enable_sdrc(void) {
    hw_reg32_t cm = (hw_reg32_t)CM_BASE;

    /* SDRC interface clock */
    reg_set32(cm + CM_ICLKEN1_CORE, (1 << 2));

    delay_cycles(500);
    while (!(reg_read32(cm + CM_IDLEST1_CORE) & (1 << 2)))
        ;
}

void power_seq_wait(void) {
    /* Power sequencing from power-tree.json:
       P5V0:  0ms
       P3V3:  10ms
       P1V8:  20ms
       P1V2:  30ms
       P1V0:  50ms
       Total: ~50ms for all rails stable */
    delay_cycles(CPU_CLK_HZ / 20);   /* ~50ms at ~600MHz */
}