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