summaryrefslogtreecommitdiff
path: root/bsp/ls2kdev/drivers/clk.c
blob: b9197134903a6427d25a144f109d5d33f16a3af3 (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
/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2017-09-06     勤为本       first version
 *
 * Copyright (c) 2020, duhuanpeng<[email protected]>
 * legacy driver APIs from loongson 1C BSP.
 */

#include <rtthread.h>
#include "ls2k1000.h"

struct loongson_pll
{
    rt_uint64_t PLL_SYS_0;
    rt_uint64_t PLL_SYS_1;
    rt_uint64_t PLL_DDR_0;
    rt_uint64_t PLL_DDR_1;
    rt_uint64_t PLL_DC_0;
    rt_uint64_t PLL_DC_1;
    rt_uint64_t PLL_PIX0_0;
    rt_uint64_t PLL_PIX0_1;
    rt_uint64_t PLL_PIX1_0;
    rt_uint64_t PLL_PIX1_1;
    rt_uint64_t FREQSCALE;
};

/* See the Schematic */
#define SYS_CLKSEL1 1
#define SYS_CLKSEL0 0

/* bit field helpers. */
#define __M(n)               (~(~0<<(n)))
#define __RBF(number, n)     ((number)&__M(n))
#define __BF(number, n, m)   __RBF((number>>m), (n-m+1))
#define BF(number, n, m)     (m<n ? __BF(number, n, m) : __BF(number, m, n))

int refclk = 100;
int gmac_clock = 125;

volatile struct loongson_pll *pll = (void *)PLL_SYS_BASE;


unsigned long clk_get_pll_rate(void)
{
    return -RT_ENOSYS;

}

unsigned long clk_get_cpu_rate(void)
{
    unsigned long node_clock;
    int l1_div_ref;
    int l1_div_loopc;
    int l2_div_out_node;

    l1_div_ref      = BF(pll->PLL_SYS_0, 26, 31);
    l1_div_loopc    = BF(pll->PLL_SYS_0, 32, 41);
    l2_div_out_node = BF(pll->PLL_SYS_1,  5,  0);

    node_clock = refclk / l1_div_ref * l1_div_loopc / l2_div_out_node;
    return node_clock;
}

unsigned long clk_get_ddr_rate(void)
{
    unsigned long ddr_clock;
    int l1_div_ref;
    int l1_div_loopc;
    int l2_div_out_ddr;

    l1_div_ref     = BF(pll->PLL_DDR_0, 26, 31);
    l1_div_loopc   = BF(pll->PLL_DDR_0, 32, 41);
    l2_div_out_ddr = BF(pll->PLL_DDR_1, 0, 5);

    ddr_clock = refclk / l1_div_ref * l1_div_loopc / l2_div_out_ddr;
    return ddr_clock;
}

unsigned long clk_get_apb_rate(void)
{
    unsigned long apb_clock;
    int apb_freqscale;

    apb_freqscale = BF(pll->FREQSCALE, 22, 20);

    /* gmac clock is fixed 125MHz */
    apb_clock = gmac_clock * (apb_freqscale + 1) / 8;
    return apb_clock;

}

unsigned long clk_get_dc_rate(void)
{
    return -RT_ENOSYS;
}