1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
4  * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
5  *
6  * Fixed rate clock implementation
7  */
8 #include "ccu.h"
9 #include "clk-fixed-rate.h"
10 #include <stdlib.h>
11 /*
12  * DOC: basic fixed-rate clock that cannot gate
13  *
14  * Traits of this clock:
15  * prepare - clk_(un)prepare only ensures parents are prepared
16  * enable - clk_enable only ensures parents are enabled
17  * rate - rate is always a fixed value.  No clk_set_rate support
18  * parent - fixed parent.  No clk_set_parent support
19  */
20 
clk_fixed_rate_recalc_rate(struct clk_hw * hw,unsigned long parent_rate)21 static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
22         unsigned long parent_rate)
23 {
24     return to_clk_fixed_rate(hw)->fixed_rate;
25 }
26 
clk_fixed_rate_recalc_accuracy(struct clk_hw * hw,unsigned long parent_accuracy)27 static unsigned long clk_fixed_rate_recalc_accuracy(struct clk_hw *hw,
28         unsigned long parent_accuracy)
29 {
30     return to_clk_fixed_rate(hw)->fixed_accuracy;
31 }
32 
33 const struct clk_ops clk_fixed_rate_ops =
34 {
35     .recalc_rate = clk_fixed_rate_recalc_rate,
36     .recalc_accuracy = clk_fixed_rate_recalc_accuracy,
37 };
38 
39 /**
40  * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
41  * the clock framework
42  * @dev: device that is registering this clock
43  * @name: name of this clock
44  * @parent_name: name of clock's parent
45  * @flags: framework-specific flags
46  * @fixed_rate: non-adjustable clock rate
47  * @fixed_accuracy: non-adjustable clock rate
48  */
clk_hw_register_fixed_rate_with_accuracy(const char * name,u32 id,const char * parent_name,unsigned long flags,unsigned long fixed_rate,unsigned long fixed_accuracy)49 int clk_hw_register_fixed_rate_with_accuracy(
50     const char *name, u32 id, const char *parent_name, unsigned long flags,
51     unsigned long fixed_rate, unsigned long fixed_accuracy)
52 {
53     struct clk_fixed_rate *fixed;
54     struct clk_hw *hw;
55     struct clk_init_data init;
56     int ret;
57 
58     /* allocate fixed-rate clock */
59     fixed = (struct clk_fixed_rate *)malloc(sizeof(*fixed));
60     if (!fixed)
61     {
62         return -1;
63     }
64 
65     init.name = name;
66     init.ops = &clk_fixed_rate_ops;
67     init.flags = flags;
68     init.parent_names = (parent_name ? &parent_name : NULL);
69     init.num_parents = (parent_name ? 1 : 0);
70 
71     /* struct clk_fixed_rate assignments */
72     fixed->fixed_rate = fixed_rate;
73     fixed->fixed_accuracy = fixed_accuracy;
74     fixed->hw.init = &init;
75 
76     /* register the clock */
77     hw = &fixed->hw;
78     hw->type = HAL_SUNXI_FIXED_CCU;
79     hw->id = id;
80     ret = clk_hw_register(hw);
81     if (ret)
82     {
83         free(fixed);
84         hw = NULL;
85         return -1;
86     }
87 
88     return 0;
89 }
90 
clk_register_fixed_rate_with_accuracy(const char * name,u32 id,const char * parent_name,unsigned long flags,unsigned long fixed_rate,unsigned long fixed_accuracy)91 int clk_register_fixed_rate_with_accuracy(const char *name, u32 id,
92         const char *parent_name, unsigned long flags,
93         unsigned long fixed_rate, unsigned long fixed_accuracy)
94 {
95     return clk_hw_register_fixed_rate_with_accuracy(name, id, parent_name,
96             flags, fixed_rate, fixed_accuracy);
97 }
98 
sunxi_fixed_clk_init(void)99 int sunxi_fixed_clk_init(void)
100 {
101     int ret = -1;
102 
103     ret = clk_register_fixed_rate_with_accuracy("dcxo24M", CLK_SRC_HOSC24M, NULL, 0, 24000000, 0);
104     if (ret)
105     {
106         printf("register clock dcxo24M error\n");
107     }
108 
109     ret = clk_register_fixed_rate_with_accuracy("fix_losc", CLK_SRC_LOSC, NULL, 0, 32768, 0);
110     if (ret)
111     {
112         printf("register clock dcxo24M error\n");
113     }
114 
115     ret = clk_register_fixed_rate_with_accuracy("rc-16m", CLK_SRC_RC_16M, NULL, 0, 16000000, 300000000);
116     if (ret)
117     {
118         printf("register clock dcxo24M error\n");
119     }
120 
121     ret = clk_register_fixed_rate_with_accuracy("ext-32k", CLK_SRC_EXT_32K, NULL, 0, 32768, 0);
122     if (ret)
123     {
124         printf("register clock dcxo24M error\n");
125     }
126 
127     return ret;
128 }
129