xref: /openbmc/linux/drivers/clk/at91/clk-main.c (revision 8a10bc9d)
1 /*
2  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  */
10 
11 #include <linux/clk-provider.h>
12 #include <linux/clkdev.h>
13 #include <linux/clk/at91_pmc.h>
14 #include <linux/delay.h>
15 #include <linux/of.h>
16 #include <linux/of_address.h>
17 #include <linux/of_irq.h>
18 #include <linux/io.h>
19 #include <linux/interrupt.h>
20 #include <linux/irq.h>
21 #include <linux/sched.h>
22 #include <linux/wait.h>
23 
24 #include "pmc.h"
25 
26 #define SLOW_CLOCK_FREQ		32768
27 #define MAINF_DIV		16
28 #define MAINFRDY_TIMEOUT	(((MAINF_DIV + 1) * USEC_PER_SEC) / \
29 				 SLOW_CLOCK_FREQ)
30 #define MAINF_LOOP_MIN_WAIT	(USEC_PER_SEC / SLOW_CLOCK_FREQ)
31 #define MAINF_LOOP_MAX_WAIT	MAINFRDY_TIMEOUT
32 
33 struct clk_main {
34 	struct clk_hw hw;
35 	struct at91_pmc *pmc;
36 	unsigned long rate;
37 	unsigned int irq;
38 	wait_queue_head_t wait;
39 };
40 
41 #define to_clk_main(hw) container_of(hw, struct clk_main, hw)
42 
43 static irqreturn_t clk_main_irq_handler(int irq, void *dev_id)
44 {
45 	struct clk_main *clkmain = (struct clk_main *)dev_id;
46 
47 	wake_up(&clkmain->wait);
48 	disable_irq_nosync(clkmain->irq);
49 
50 	return IRQ_HANDLED;
51 }
52 
53 static int clk_main_prepare(struct clk_hw *hw)
54 {
55 	struct clk_main *clkmain = to_clk_main(hw);
56 	struct at91_pmc *pmc = clkmain->pmc;
57 	unsigned long halt_time, timeout;
58 	u32 tmp;
59 
60 	while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS)) {
61 		enable_irq(clkmain->irq);
62 		wait_event(clkmain->wait,
63 			   pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS);
64 	}
65 
66 	if (clkmain->rate)
67 		return 0;
68 
69 	timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT);
70 	do {
71 		halt_time = jiffies;
72 		tmp = pmc_read(pmc, AT91_CKGR_MCFR);
73 		if (tmp & AT91_PMC_MAINRDY)
74 			return 0;
75 		usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
76 	} while (time_before(halt_time, timeout));
77 
78 	return 0;
79 }
80 
81 static int clk_main_is_prepared(struct clk_hw *hw)
82 {
83 	struct clk_main *clkmain = to_clk_main(hw);
84 
85 	return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCS);
86 }
87 
88 static unsigned long clk_main_recalc_rate(struct clk_hw *hw,
89 					  unsigned long parent_rate)
90 {
91 	u32 tmp;
92 	struct clk_main *clkmain = to_clk_main(hw);
93 	struct at91_pmc *pmc = clkmain->pmc;
94 
95 	if (clkmain->rate)
96 		return clkmain->rate;
97 
98 	tmp = pmc_read(pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINF;
99 	clkmain->rate = (tmp * parent_rate) / MAINF_DIV;
100 
101 	return clkmain->rate;
102 }
103 
104 static const struct clk_ops main_ops = {
105 	.prepare = clk_main_prepare,
106 	.is_prepared = clk_main_is_prepared,
107 	.recalc_rate = clk_main_recalc_rate,
108 };
109 
110 static struct clk * __init
111 at91_clk_register_main(struct at91_pmc *pmc,
112 		       unsigned int irq,
113 		       const char *name,
114 		       const char *parent_name,
115 		       unsigned long rate)
116 {
117 	int ret;
118 	struct clk_main *clkmain;
119 	struct clk *clk = NULL;
120 	struct clk_init_data init;
121 
122 	if (!pmc || !irq || !name)
123 		return ERR_PTR(-EINVAL);
124 
125 	if (!rate && !parent_name)
126 		return ERR_PTR(-EINVAL);
127 
128 	clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL);
129 	if (!clkmain)
130 		return ERR_PTR(-ENOMEM);
131 
132 	init.name = name;
133 	init.ops = &main_ops;
134 	init.parent_names = parent_name ? &parent_name : NULL;
135 	init.num_parents = parent_name ? 1 : 0;
136 	init.flags = parent_name ? 0 : CLK_IS_ROOT;
137 
138 	clkmain->hw.init = &init;
139 	clkmain->rate = rate;
140 	clkmain->pmc = pmc;
141 	clkmain->irq = irq;
142 	init_waitqueue_head(&clkmain->wait);
143 	irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN);
144 	ret = request_irq(clkmain->irq, clk_main_irq_handler,
145 			  IRQF_TRIGGER_HIGH, "clk-main", clkmain);
146 	if (ret)
147 		return ERR_PTR(ret);
148 
149 	clk = clk_register(NULL, &clkmain->hw);
150 	if (IS_ERR(clk)) {
151 		free_irq(clkmain->irq, clkmain);
152 		kfree(clkmain);
153 	}
154 
155 	return clk;
156 }
157 
158 
159 
160 static void __init
161 of_at91_clk_main_setup(struct device_node *np, struct at91_pmc *pmc)
162 {
163 	struct clk *clk;
164 	unsigned int irq;
165 	const char *parent_name;
166 	const char *name = np->name;
167 	u32 rate = 0;
168 
169 	parent_name = of_clk_get_parent_name(np, 0);
170 	of_property_read_string(np, "clock-output-names", &name);
171 	of_property_read_u32(np, "clock-frequency", &rate);
172 	irq = irq_of_parse_and_map(np, 0);
173 	if (!irq)
174 		return;
175 
176 	clk = at91_clk_register_main(pmc, irq, name, parent_name, rate);
177 	if (IS_ERR(clk))
178 		return;
179 
180 	of_clk_add_provider(np, of_clk_src_simple_get, clk);
181 }
182 
183 void __init of_at91rm9200_clk_main_setup(struct device_node *np,
184 					 struct at91_pmc *pmc)
185 {
186 	of_at91_clk_main_setup(np, pmc);
187 }
188