Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
clock.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Zhang, Keguang <[email protected]>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  */
9 
10 #include <linux/module.h>
11 #include <linux/list.h>
12 #include <linux/mutex.h>
13 #include <linux/clk.h>
14 #include <linux/err.h>
15 #include <asm/clock.h>
16 #include <asm/time.h>
17 
18 #include <loongson1.h>
19 
20 static LIST_HEAD(clocks);
21 static DEFINE_MUTEX(clocks_mutex);
22 
23 struct clk *clk_get(struct device *dev, const char *name)
24 {
25  struct clk *c;
26  struct clk *ret = NULL;
27 
28  mutex_lock(&clocks_mutex);
29  list_for_each_entry(c, &clocks, node) {
30  if (!strcmp(c->name, name)) {
31  ret = c;
32  break;
33  }
34  }
35  mutex_unlock(&clocks_mutex);
36 
37  return ret;
38 }
40 
41 int clk_enable(struct clk *clk)
42 {
43  return 0;
44 }
46 
47 void clk_disable(struct clk *clk)
48 {
49 }
51 
52 unsigned long clk_get_rate(struct clk *clk)
53 {
54  return clk->rate;
55 }
57 
58 void clk_put(struct clk *clk)
59 {
60 }
62 
63 static void pll_clk_init(struct clk *clk)
64 {
65  u32 pll;
66 
68  clk->rate = (12 + (pll & 0x3f)) * 33 / 2
69  + ((pll >> 8) & 0x3ff) * 33 / 1024 / 2;
70  clk->rate *= 1000000;
71 }
72 
73 static void cpu_clk_init(struct clk *clk)
74 {
75  u32 pll, ctrl;
76 
77  pll = clk_get_rate(clk->parent);
79  clk->rate = pll / (ctrl >> DIV_CPU_SHIFT);
80 }
81 
82 static void ddr_clk_init(struct clk *clk)
83 {
84  u32 pll, ctrl;
85 
86  pll = clk_get_rate(clk->parent);
88  clk->rate = pll / (ctrl >> DIV_DDR_SHIFT);
89 }
90 
91 static void dc_clk_init(struct clk *clk)
92 {
93  u32 pll, ctrl;
94 
95  pll = clk_get_rate(clk->parent);
97  clk->rate = pll / (ctrl >> DIV_DC_SHIFT);
98 }
99 
100 static struct clk_ops pll_clk_ops = {
101  .init = pll_clk_init,
102 };
103 
104 static struct clk_ops cpu_clk_ops = {
105  .init = cpu_clk_init,
106 };
107 
108 static struct clk_ops ddr_clk_ops = {
109  .init = ddr_clk_init,
110 };
111 
112 static struct clk_ops dc_clk_ops = {
113  .init = dc_clk_init,
114 };
115 
116 static struct clk pll_clk = {
117  .name = "pll",
118  .ops = &pll_clk_ops,
119 };
120 
121 static struct clk cpu_clk = {
122  .name = "cpu",
123  .parent = &pll_clk,
124  .ops = &cpu_clk_ops,
125 };
126 
127 static struct clk ddr_clk = {
128  .name = "ddr",
129  .parent = &pll_clk,
130  .ops = &ddr_clk_ops,
131 };
132 
133 static struct clk dc_clk = {
134  .name = "dc",
135  .parent = &pll_clk,
136  .ops = &dc_clk_ops,
137 };
138 
139 int clk_register(struct clk *clk)
140 {
141  mutex_lock(&clocks_mutex);
142  list_add(&clk->node, &clocks);
143  if (clk->ops->init)
144  clk->ops->init(clk);
145  mutex_unlock(&clocks_mutex);
146 
147  return 0;
148 }
150 
151 static struct clk *ls1x_clks[] = {
152  &pll_clk,
153  &cpu_clk,
154  &ddr_clk,
155  &dc_clk,
156 };
157 
159 {
160  int i;
161 
162  for (i = 0; i < ARRAY_SIZE(ls1x_clks); i++)
163  clk_register(ls1x_clks[i]);
164 
165  return 0;
166 }
167 
169 {
170  struct clk *clk;
171 
172  /* Initialize LS1X clocks */
173  ls1x_clock_init();
174 
175  /* setup mips r4k timer */
176  clk = clk_get(NULL, "cpu");
177  if (IS_ERR(clk))
178  panic("unable to get dc clock, err=%ld", PTR_ERR(clk));
179 
180  mips_hpt_frequency = clk_get_rate(clk) / 2;
181 }