Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cmu.c
Go to the documentation of this file.
1 /*
2  * cmu.c, Clock Mask Unit routines for the NEC VR4100 series.
3  *
4  * Copyright (C) 2001-2002 MontaVista Software Inc.
5  * Author: Yoichi Yuasa <[email protected]>
6  * Copuright (C) 2003-2005 Yoichi Yuasa <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22 /*
23  * Changes:
24  * MontaVista Software Inc. <[email protected]>
25  * - New creation, NEC VR4122 and VR4131 are supported.
26  * - Added support for NEC VR4111 and VR4121.
27  *
28  * Yoichi Yuasa <[email protected]>
29  * - Added support for NEC VR4133.
30  */
31 #include <linux/init.h>
32 #include <linux/ioport.h>
33 #include <linux/module.h>
34 #include <linux/smp.h>
35 #include <linux/spinlock.h>
36 #include <linux/types.h>
37 
38 #include <asm/cpu.h>
39 #include <asm/io.h>
40 #include <asm/vr41xx/vr41xx.h>
41 
42 #define CMU_TYPE1_BASE 0x0b000060UL
43 #define CMU_TYPE1_SIZE 0x4
44 
45 #define CMU_TYPE2_BASE 0x0f000060UL
46 #define CMU_TYPE2_SIZE 0x4
47 
48 #define CMU_TYPE3_BASE 0x0f000060UL
49 #define CMU_TYPE3_SIZE 0x8
50 
51 #define CMUCLKMSK 0x0
52  #define MSKPIU 0x0001
53  #define MSKSIU 0x0002
54  #define MSKAIU 0x0004
55  #define MSKKIU 0x0008
56  #define MSKFIR 0x0010
57  #define MSKDSIU 0x0820
58  #define MSKCSI 0x0040
59  #define MSKPCIU 0x0080
60  #define MSKSSIU 0x0100
61  #define MSKSHSP 0x0200
62  #define MSKFFIR 0x0400
63  #define MSKSCSI 0x1000
64  #define MSKPPCIU 0x2000
65 #define CMUCLKMSK2 0x4
66  #define MSKCEU 0x0001
67  #define MSKMAC0 0x0002
68  #define MSKMAC1 0x0004
69 
70 static void __iomem *cmu_base;
71 static uint16_t cmuclkmsk, cmuclkmsk2;
72 static DEFINE_SPINLOCK(cmu_lock);
73 
74 #define cmu_read(offset) readw(cmu_base + (offset))
75 #define cmu_write(offset, value) writew((value), cmu_base + (offset))
76 
78 {
79  spin_lock_irq(&cmu_lock);
80 
81  switch (clock) {
82  case PIU_CLOCK:
83  cmuclkmsk |= MSKPIU;
84  break;
85  case SIU_CLOCK:
86  cmuclkmsk |= MSKSIU | MSKSSIU;
87  break;
88  case AIU_CLOCK:
89  cmuclkmsk |= MSKAIU;
90  break;
91  case KIU_CLOCK:
92  cmuclkmsk |= MSKKIU;
93  break;
94  case FIR_CLOCK:
95  cmuclkmsk |= MSKFIR | MSKFFIR;
96  break;
97  case DSIU_CLOCK:
98  if (current_cpu_type() == CPU_VR4111 ||
100  cmuclkmsk |= MSKDSIU;
101  else
102  cmuclkmsk |= MSKSIU | MSKDSIU;
103  break;
104  case CSI_CLOCK:
105  cmuclkmsk |= MSKCSI | MSKSCSI;
106  break;
107  case PCIU_CLOCK:
108  cmuclkmsk |= MSKPCIU;
109  break;
110  case HSP_CLOCK:
111  cmuclkmsk |= MSKSHSP;
112  break;
113  case PCI_CLOCK:
114  cmuclkmsk |= MSKPPCIU;
115  break;
116  case CEU_CLOCK:
117  cmuclkmsk2 |= MSKCEU;
118  break;
119  case ETHER0_CLOCK:
120  cmuclkmsk2 |= MSKMAC0;
121  break;
122  case ETHER1_CLOCK:
123  cmuclkmsk2 |= MSKMAC1;
124  break;
125  default:
126  break;
127  }
128 
129  if (clock == CEU_CLOCK || clock == ETHER0_CLOCK ||
130  clock == ETHER1_CLOCK)
131  cmu_write(CMUCLKMSK2, cmuclkmsk2);
132  else
133  cmu_write(CMUCLKMSK, cmuclkmsk);
134 
135  spin_unlock_irq(&cmu_lock);
136 }
137 
139 
141 {
142  spin_lock_irq(&cmu_lock);
143 
144  switch (clock) {
145  case PIU_CLOCK:
146  cmuclkmsk &= ~MSKPIU;
147  break;
148  case SIU_CLOCK:
149  if (current_cpu_type() == CPU_VR4111 ||
151  cmuclkmsk &= ~(MSKSIU | MSKSSIU);
152  } else {
153  if (cmuclkmsk & MSKDSIU)
154  cmuclkmsk &= ~MSKSSIU;
155  else
156  cmuclkmsk &= ~(MSKSIU | MSKSSIU);
157  }
158  break;
159  case AIU_CLOCK:
160  cmuclkmsk &= ~MSKAIU;
161  break;
162  case KIU_CLOCK:
163  cmuclkmsk &= ~MSKKIU;
164  break;
165  case FIR_CLOCK:
166  cmuclkmsk &= ~(MSKFIR | MSKFFIR);
167  break;
168  case DSIU_CLOCK:
169  if (current_cpu_type() == CPU_VR4111 ||
171  cmuclkmsk &= ~MSKDSIU;
172  } else {
173  if (cmuclkmsk & MSKSSIU)
174  cmuclkmsk &= ~MSKDSIU;
175  else
176  cmuclkmsk &= ~(MSKSIU | MSKDSIU);
177  }
178  break;
179  case CSI_CLOCK:
180  cmuclkmsk &= ~(MSKCSI | MSKSCSI);
181  break;
182  case PCIU_CLOCK:
183  cmuclkmsk &= ~MSKPCIU;
184  break;
185  case HSP_CLOCK:
186  cmuclkmsk &= ~MSKSHSP;
187  break;
188  case PCI_CLOCK:
189  cmuclkmsk &= ~MSKPPCIU;
190  break;
191  case CEU_CLOCK:
192  cmuclkmsk2 &= ~MSKCEU;
193  break;
194  case ETHER0_CLOCK:
195  cmuclkmsk2 &= ~MSKMAC0;
196  break;
197  case ETHER1_CLOCK:
198  cmuclkmsk2 &= ~MSKMAC1;
199  break;
200  default:
201  break;
202  }
203 
204  if (clock == CEU_CLOCK || clock == ETHER0_CLOCK ||
205  clock == ETHER1_CLOCK)
206  cmu_write(CMUCLKMSK2, cmuclkmsk2);
207  else
208  cmu_write(CMUCLKMSK, cmuclkmsk);
209 
210  spin_unlock_irq(&cmu_lock);
211 }
212 
214 
215 static int __init vr41xx_cmu_init(void)
216 {
217  unsigned long start, size;
218 
219  switch (current_cpu_type()) {
220  case CPU_VR4111:
221  case CPU_VR4121:
222  start = CMU_TYPE1_BASE;
223  size = CMU_TYPE1_SIZE;
224  break;
225  case CPU_VR4122:
226  case CPU_VR4131:
227  start = CMU_TYPE2_BASE;
228  size = CMU_TYPE2_SIZE;
229  break;
230  case CPU_VR4133:
231  start = CMU_TYPE3_BASE;
232  size = CMU_TYPE3_SIZE;
233  break;
234  default:
235  panic("Unexpected CPU of NEC VR4100 series");
236  break;
237  }
238 
239  if (request_mem_region(start, size, "CMU") == NULL)
240  return -EBUSY;
241 
242  cmu_base = ioremap(start, size);
243  if (cmu_base == NULL) {
244  release_mem_region(start, size);
245  return -EBUSY;
246  }
247 
248  cmuclkmsk = cmu_read(CMUCLKMSK);
249  if (current_cpu_type() == CPU_VR4133)
250  cmuclkmsk2 = cmu_read(CMUCLKMSK2);
251 
252  spin_lock_init(&cmu_lock);
253 
254  return 0;
255 }
256 
257 core_initcall(vr41xx_cmu_init);