1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * cmu.c, Clock Mask Unit routines for the NEC VR4100 series.
5 * Copyright (C) 2001-2002 MontaVista Software Inc.
6 * Author: Yoichi Yuasa <source@mvista.com>
7 * Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@linux-mips.org>
11 * MontaVista Software Inc. <source@mvista.com>
12 * - New creation, NEC VR4122 and VR4131 are supported.
13 * - Added support for NEC VR4111 and VR4121.
15 * Yoichi Yuasa <yuasa@linux-mips.org>
16 * - Added support for NEC VR4133.
18 #include <linux/export.h>
19 #include <linux/init.h>
20 #include <linux/ioport.h>
21 #include <linux/smp.h>
22 #include <linux/spinlock.h>
23 #include <linux/types.h>
27 #include <asm/vr41xx/vr41xx.h>
29 #define CMU_TYPE1_BASE 0x0b000060UL
30 #define CMU_TYPE1_SIZE 0x4
32 #define CMU_TYPE2_BASE 0x0f000060UL
33 #define CMU_TYPE2_SIZE 0x4
35 #define CMU_TYPE3_BASE 0x0f000060UL
36 #define CMU_TYPE3_SIZE 0x8
44 #define MSKDSIU 0x0820
46 #define MSKPCIU 0x0080
47 #define MSKSSIU 0x0100
48 #define MSKSHSP 0x0200
49 #define MSKFFIR 0x0400
50 #define MSKSCSI 0x1000
51 #define MSKPPCIU 0x2000
52 #define CMUCLKMSK2 0x4
54 #define MSKMAC0 0x0002
55 #define MSKMAC1 0x0004
57 static void __iomem
*cmu_base
;
58 static uint16_t cmuclkmsk
, cmuclkmsk2
;
59 static DEFINE_SPINLOCK(cmu_lock
);
61 #define cmu_read(offset) readw(cmu_base + (offset))
62 #define cmu_write(offset, value) writew((value), cmu_base + (offset))
64 void vr41xx_supply_clock(vr41xx_clock_t clock
)
66 spin_lock_irq(&cmu_lock
);
73 cmuclkmsk
|= MSKSIU
| MSKSSIU
;
82 cmuclkmsk
|= MSKFIR
| MSKFFIR
;
85 if (current_cpu_type() == CPU_VR4111
||
86 current_cpu_type() == CPU_VR4121
)
89 cmuclkmsk
|= MSKSIU
| MSKDSIU
;
92 cmuclkmsk
|= MSKCSI
| MSKSCSI
;
101 cmuclkmsk
|= MSKPPCIU
;
104 cmuclkmsk2
|= MSKCEU
;
107 cmuclkmsk2
|= MSKMAC0
;
110 cmuclkmsk2
|= MSKMAC1
;
116 if (clock
== CEU_CLOCK
|| clock
== ETHER0_CLOCK
||
117 clock
== ETHER1_CLOCK
)
118 cmu_write(CMUCLKMSK2
, cmuclkmsk2
);
120 cmu_write(CMUCLKMSK
, cmuclkmsk
);
122 spin_unlock_irq(&cmu_lock
);
125 EXPORT_SYMBOL_GPL(vr41xx_supply_clock
);
127 void vr41xx_mask_clock(vr41xx_clock_t clock
)
129 spin_lock_irq(&cmu_lock
);
133 cmuclkmsk
&= ~MSKPIU
;
136 if (current_cpu_type() == CPU_VR4111
||
137 current_cpu_type() == CPU_VR4121
) {
138 cmuclkmsk
&= ~(MSKSIU
| MSKSSIU
);
140 if (cmuclkmsk
& MSKDSIU
)
141 cmuclkmsk
&= ~MSKSSIU
;
143 cmuclkmsk
&= ~(MSKSIU
| MSKSSIU
);
147 cmuclkmsk
&= ~MSKAIU
;
150 cmuclkmsk
&= ~MSKKIU
;
153 cmuclkmsk
&= ~(MSKFIR
| MSKFFIR
);
156 if (current_cpu_type() == CPU_VR4111
||
157 current_cpu_type() == CPU_VR4121
) {
158 cmuclkmsk
&= ~MSKDSIU
;
160 if (cmuclkmsk
& MSKSSIU
)
161 cmuclkmsk
&= ~MSKDSIU
;
163 cmuclkmsk
&= ~(MSKSIU
| MSKDSIU
);
167 cmuclkmsk
&= ~(MSKCSI
| MSKSCSI
);
170 cmuclkmsk
&= ~MSKPCIU
;
173 cmuclkmsk
&= ~MSKSHSP
;
176 cmuclkmsk
&= ~MSKPPCIU
;
179 cmuclkmsk2
&= ~MSKCEU
;
182 cmuclkmsk2
&= ~MSKMAC0
;
185 cmuclkmsk2
&= ~MSKMAC1
;
191 if (clock
== CEU_CLOCK
|| clock
== ETHER0_CLOCK
||
192 clock
== ETHER1_CLOCK
)
193 cmu_write(CMUCLKMSK2
, cmuclkmsk2
);
195 cmu_write(CMUCLKMSK
, cmuclkmsk
);
197 spin_unlock_irq(&cmu_lock
);
200 EXPORT_SYMBOL_GPL(vr41xx_mask_clock
);
202 static int __init
vr41xx_cmu_init(void)
204 unsigned long start
, size
;
206 switch (current_cpu_type()) {
209 start
= CMU_TYPE1_BASE
;
210 size
= CMU_TYPE1_SIZE
;
214 start
= CMU_TYPE2_BASE
;
215 size
= CMU_TYPE2_SIZE
;
218 start
= CMU_TYPE3_BASE
;
219 size
= CMU_TYPE3_SIZE
;
222 panic("Unexpected CPU of NEC VR4100 series");
226 if (request_mem_region(start
, size
, "CMU") == NULL
)
229 cmu_base
= ioremap(start
, size
);
230 if (cmu_base
== NULL
) {
231 release_mem_region(start
, size
);
235 cmuclkmsk
= cmu_read(CMUCLKMSK
);
236 if (current_cpu_type() == CPU_VR4133
)
237 cmuclkmsk2
= cmu_read(CMUCLKMSK2
);
239 spin_lock_init(&cmu_lock
);
244 core_initcall(vr41xx_cmu_init
);