1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2017-09-06     勤为本       first version
9  *
10  * Copyright (c) 2020, duhuanpeng<548708880@qq.com>
11  * legacy driver APIs from loongson 1C BSP.
12  */
13 
14 #include <rtthread.h>
15 #include "ls2k1000.h"
16 
17 struct loongson_pll
18 {
19     rt_uint64_t PLL_SYS_0;
20     rt_uint64_t PLL_SYS_1;
21     rt_uint64_t PLL_DDR_0;
22     rt_uint64_t PLL_DDR_1;
23     rt_uint64_t PLL_DC_0;
24     rt_uint64_t PLL_DC_1;
25     rt_uint64_t PLL_PIX0_0;
26     rt_uint64_t PLL_PIX0_1;
27     rt_uint64_t PLL_PIX1_0;
28     rt_uint64_t PLL_PIX1_1;
29     rt_uint64_t FREQSCALE;
30 };
31 
32 /* See the Schematic */
33 #define SYS_CLKSEL1 1
34 #define SYS_CLKSEL0 0
35 
36 /* bit field helpers. */
37 #define __M(n)               (~(~0<<(n)))
38 #define __RBF(number, n)     ((number)&__M(n))
39 #define __BF(number, n, m)   __RBF((number>>m), (n-m+1))
40 #define BF(number, n, m)     (m<n ? __BF(number, n, m) : __BF(number, m, n))
41 
42 int refclk = 100;
43 int gmac_clock = 125;
44 
45 volatile struct loongson_pll *pll = (void *)PLL_SYS_BASE;
46 
47 
clk_get_pll_rate(void)48 unsigned long clk_get_pll_rate(void)
49 {
50     return -RT_ENOSYS;
51 
52 }
53 
clk_get_cpu_rate(void)54 unsigned long clk_get_cpu_rate(void)
55 {
56     unsigned long node_clock;
57     int l1_div_ref;
58     int l1_div_loopc;
59     int l2_div_out_node;
60 
61     l1_div_ref      = BF(pll->PLL_SYS_0, 26, 31);
62     l1_div_loopc    = BF(pll->PLL_SYS_0, 32, 41);
63     l2_div_out_node = BF(pll->PLL_SYS_1,  5,  0);
64 
65     node_clock = refclk / l1_div_ref * l1_div_loopc / l2_div_out_node;
66     return node_clock;
67 }
68 
clk_get_ddr_rate(void)69 unsigned long clk_get_ddr_rate(void)
70 {
71     unsigned long ddr_clock;
72     int l1_div_ref;
73     int l1_div_loopc;
74     int l2_div_out_ddr;
75 
76     l1_div_ref     = BF(pll->PLL_DDR_0, 26, 31);
77     l1_div_loopc   = BF(pll->PLL_DDR_0, 32, 41);
78     l2_div_out_ddr = BF(pll->PLL_DDR_1, 0, 5);
79 
80     ddr_clock = refclk / l1_div_ref * l1_div_loopc / l2_div_out_ddr;
81     return ddr_clock;
82 }
83 
clk_get_apb_rate(void)84 unsigned long clk_get_apb_rate(void)
85 {
86     unsigned long apb_clock;
87     int apb_freqscale;
88 
89     apb_freqscale = BF(pll->FREQSCALE, 22, 20);
90 
91     /* gmac clock is fixed 125MHz */
92     apb_clock = gmac_clock * (apb_freqscale + 1) / 8;
93     return apb_clock;
94 
95 }
96 
clk_get_dc_rate(void)97 unsigned long clk_get_dc_rate(void)
98 {
99     return -RT_ENOSYS;
100 }
101