| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  cmu.c, Clock Mask Unit routines for the NEC VR4100 series. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Copyright (C) 2001-2002  MontaVista Software Inc. | 
					
						
							| 
									
										
										
										
											2009-07-03 00:39:38 +09:00
										 |  |  |  *    Author: Yoichi Yuasa <source@mvista.com> | 
					
						
							|  |  |  |  *  Copuright (C) 2003-2005  Yoichi Yuasa <yuasa@linux-mips.org> | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  *  it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  *  the Free Software Foundation; either version 2 of the License, or | 
					
						
							|  |  |  |  *  (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  *  GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  *  along with this program; if not, write to the Free Software | 
					
						
							|  |  |  |  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Changes: | 
					
						
							| 
									
										
										
										
											2009-07-03 00:39:38 +09:00
										 |  |  |  *  MontaVista Software Inc. <source@mvista.com> | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |  *  - New creation, NEC VR4122 and VR4131 are supported. | 
					
						
							|  |  |  |  *  - Added support for NEC VR4111 and VR4121. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-07-03 00:39:38 +09:00
										 |  |  |  *  Yoichi Yuasa <yuasa@linux-mips.org> | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |  *  - Added support for NEC VR4133. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <linux/init.h>
 | 
					
						
							|  |  |  | #include <linux/ioport.h>
 | 
					
						
							|  |  |  | #include <linux/module.h>
 | 
					
						
							|  |  |  | #include <linux/smp.h>
 | 
					
						
							|  |  |  | #include <linux/spinlock.h>
 | 
					
						
							|  |  |  | #include <linux/types.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <asm/cpu.h>
 | 
					
						
							|  |  |  | #include <asm/io.h>
 | 
					
						
							|  |  |  | #include <asm/vr41xx/vr41xx.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CMU_TYPE1_BASE	0x0b000060UL
 | 
					
						
							|  |  |  | #define CMU_TYPE1_SIZE	0x4
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CMU_TYPE2_BASE	0x0f000060UL
 | 
					
						
							|  |  |  | #define CMU_TYPE2_SIZE	0x4
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CMU_TYPE3_BASE	0x0f000060UL
 | 
					
						
							|  |  |  | #define CMU_TYPE3_SIZE	0x8
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CMUCLKMSK	0x0
 | 
					
						
							|  |  |  |  #define MSKPIU		0x0001
 | 
					
						
							|  |  |  |  #define MSKSIU		0x0002
 | 
					
						
							|  |  |  |  #define MSKAIU		0x0004
 | 
					
						
							|  |  |  |  #define MSKKIU		0x0008
 | 
					
						
							|  |  |  |  #define MSKFIR		0x0010
 | 
					
						
							|  |  |  |  #define MSKDSIU	0x0820
 | 
					
						
							|  |  |  |  #define MSKCSI		0x0040
 | 
					
						
							|  |  |  |  #define MSKPCIU	0x0080
 | 
					
						
							|  |  |  |  #define MSKSSIU	0x0100
 | 
					
						
							|  |  |  |  #define MSKSHSP	0x0200
 | 
					
						
							|  |  |  |  #define MSKFFIR	0x0400
 | 
					
						
							|  |  |  |  #define MSKSCSI	0x1000
 | 
					
						
							|  |  |  |  #define MSKPPCIU	0x2000
 | 
					
						
							|  |  |  | #define CMUCLKMSK2	0x4
 | 
					
						
							|  |  |  |  #define MSKCEU		0x0001
 | 
					
						
							|  |  |  |  #define MSKMAC0	0x0002
 | 
					
						
							|  |  |  |  #define MSKMAC1	0x0004
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void __iomem *cmu_base; | 
					
						
							|  |  |  | static uint16_t cmuclkmsk, cmuclkmsk2; | 
					
						
							| 
									
										
										
										
											2005-10-03 13:41:19 +01:00
										 |  |  | static DEFINE_SPINLOCK(cmu_lock); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define cmu_read(offset)		readw(cmu_base + (offset))
 | 
					
						
							|  |  |  | #define cmu_write(offset, value)	writew((value), cmu_base + (offset))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void vr41xx_supply_clock(vr41xx_clock_t clock) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	spin_lock_irq(&cmu_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (clock) { | 
					
						
							|  |  |  | 	case PIU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk |= MSKPIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SIU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk |= MSKSIU | MSKSSIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AIU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk |= MSKAIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case KIU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk |= MSKKIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case FIR_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk |= MSKFIR | MSKFFIR; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case DSIU_CLOCK: | 
					
						
							| 
									
										
										
										
											2007-10-11 23:46:15 +01:00
										 |  |  | 		if (current_cpu_type() == CPU_VR4111 || | 
					
						
							|  |  |  | 		    current_cpu_type() == CPU_VR4121) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 			cmuclkmsk |= MSKDSIU; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			cmuclkmsk |= MSKSIU | MSKDSIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case CSI_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk |= MSKCSI | MSKSCSI; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case PCIU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk |= MSKPCIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case HSP_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk |= MSKSHSP; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case PCI_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk |= MSKPPCIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case CEU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk2 |= MSKCEU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case ETHER0_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk2 |= MSKMAC0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case ETHER1_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk2 |= MSKMAC1; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (clock == CEU_CLOCK || clock == ETHER0_CLOCK || | 
					
						
							|  |  |  | 	    clock == ETHER1_CLOCK) | 
					
						
							|  |  |  | 		cmu_write(CMUCLKMSK2, cmuclkmsk2); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		cmu_write(CMUCLKMSK, cmuclkmsk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_unlock_irq(&cmu_lock); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EXPORT_SYMBOL_GPL(vr41xx_supply_clock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void vr41xx_mask_clock(vr41xx_clock_t clock) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	spin_lock_irq(&cmu_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (clock) { | 
					
						
							|  |  |  | 	case PIU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk &= ~MSKPIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case SIU_CLOCK: | 
					
						
							| 
									
										
										
										
											2007-10-11 23:46:15 +01:00
										 |  |  | 		if (current_cpu_type() == CPU_VR4111 || | 
					
						
							|  |  |  | 		    current_cpu_type() == CPU_VR4121) { | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 			cmuclkmsk &= ~(MSKSIU | MSKSSIU); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if (cmuclkmsk & MSKDSIU) | 
					
						
							|  |  |  | 				cmuclkmsk &= ~MSKSSIU; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				cmuclkmsk &= ~(MSKSIU | MSKSSIU); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AIU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk &= ~MSKAIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case KIU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk &= ~MSKKIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case FIR_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk &= ~(MSKFIR | MSKFFIR); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case DSIU_CLOCK: | 
					
						
							| 
									
										
										
										
											2007-10-11 23:46:15 +01:00
										 |  |  | 		if (current_cpu_type() == CPU_VR4111 || | 
					
						
							|  |  |  | 		    current_cpu_type() == CPU_VR4121) { | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 			cmuclkmsk &= ~MSKDSIU; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if (cmuclkmsk & MSKSSIU) | 
					
						
							|  |  |  | 				cmuclkmsk &= ~MSKDSIU; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				cmuclkmsk &= ~(MSKSIU | MSKDSIU); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case CSI_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk &= ~(MSKCSI | MSKSCSI); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case PCIU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk &= ~MSKPCIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case HSP_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk &= ~MSKSHSP; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case PCI_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk &= ~MSKPPCIU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case CEU_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk2 &= ~MSKCEU; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case ETHER0_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk2 &= ~MSKMAC0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case ETHER1_CLOCK: | 
					
						
							|  |  |  | 		cmuclkmsk2 &= ~MSKMAC1; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (clock == CEU_CLOCK || clock == ETHER0_CLOCK || | 
					
						
							|  |  |  | 	    clock == ETHER1_CLOCK) | 
					
						
							|  |  |  | 		cmu_write(CMUCLKMSK2, cmuclkmsk2); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		cmu_write(CMUCLKMSK, cmuclkmsk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_unlock_irq(&cmu_lock); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EXPORT_SYMBOL_GPL(vr41xx_mask_clock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int __init vr41xx_cmu_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long start, size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-11 23:46:15 +01:00
										 |  |  | 	switch (current_cpu_type()) { | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  | 	case CPU_VR4111: | 
					
						
							|  |  |  | 	case CPU_VR4121: | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		start = CMU_TYPE1_BASE; | 
					
						
							|  |  |  | 		size = CMU_TYPE1_SIZE; | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case CPU_VR4122: | 
					
						
							|  |  |  | 	case CPU_VR4131: | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		start = CMU_TYPE2_BASE; | 
					
						
							|  |  |  | 		size = CMU_TYPE2_SIZE; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  | 	case CPU_VR4133: | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		start = CMU_TYPE3_BASE; | 
					
						
							|  |  |  | 		size = CMU_TYPE3_SIZE; | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		panic("Unexpected CPU of NEC VR4100 series"); | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2013-01-22 12:59:30 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (request_mem_region(start, size, "CMU") == NULL) | 
					
						
							|  |  |  | 		return -EBUSY; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cmu_base = ioremap(start, size); | 
					
						
							|  |  |  | 	if (cmu_base == NULL) { | 
					
						
							|  |  |  | 		release_mem_region(start, size); | 
					
						
							|  |  |  | 		return -EBUSY; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cmuclkmsk = cmu_read(CMUCLKMSK); | 
					
						
							| 
									
										
										
										
											2007-10-11 23:46:15 +01:00
										 |  |  | 	if (current_cpu_type() == CPU_VR4133) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		cmuclkmsk2 = cmu_read(CMUCLKMSK2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_init(&cmu_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | core_initcall(vr41xx_cmu_init); |