| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * arch/arm/mach-u300/clock.c | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 2007-2009 ST-Ericsson AB | 
					
						
							|  |  |  |  * License terms: GNU General Public License (GPL) version 2 | 
					
						
							|  |  |  |  * Define clocks in the app platform. | 
					
						
							|  |  |  |  * Author: Linus Walleij <linus.walleij@stericsson.com> | 
					
						
							|  |  |  |  * Author: Jonas Aaberg <jonas.aberg@stericsson.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <linux/module.h>
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/list.h>
 | 
					
						
							|  |  |  | #include <linux/errno.h>
 | 
					
						
							|  |  |  | #include <linux/err.h>
 | 
					
						
							|  |  |  | #include <linux/string.h>
 | 
					
						
							|  |  |  | #include <linux/clk.h>
 | 
					
						
							|  |  |  | #include <linux/mutex.h>
 | 
					
						
							|  |  |  | #include <linux/spinlock.h>
 | 
					
						
							|  |  |  | #include <linux/debugfs.h>
 | 
					
						
							|  |  |  | #include <linux/device.h>
 | 
					
						
							|  |  |  | #include <linux/init.h>
 | 
					
						
							|  |  |  | #include <linux/timer.h>
 | 
					
						
							|  |  |  | #include <linux/io.h>
 | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | #include <linux/seq_file.h>
 | 
					
						
							| 
									
										
										
										
											2010-11-17 10:04:33 +01:00
										 |  |  | #include <linux/clkdev.h>
 | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <mach/hardware.h>
 | 
					
						
							|  |  |  | #include <mach/syscon.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "clock.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * TODO: | 
					
						
							|  |  |  |  * - move all handling of the CCR register into this file and create | 
					
						
							|  |  |  |  *   a spinlock for the CCR register | 
					
						
							|  |  |  |  * - switch to the clkdevice lookup mechanism that maps clocks to | 
					
						
							|  |  |  |  *   device ID:s instead when it becomes available in kernel 2.6.29. | 
					
						
							|  |  |  |  * - implement rate get/set for all clocks that need it. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Syscon clock I/O registers lock so clock requests don't collide | 
					
						
							|  |  |  |  * NOTE: this is a local lock only used to lock access to clock and | 
					
						
							|  |  |  |  * reset registers in syscon. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static DEFINE_SPINLOCK(syscon_clkreg_lock); | 
					
						
							|  |  |  | static DEFINE_SPINLOCK(syscon_resetreg_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * The clocking hierarchy currently looks like this. | 
					
						
							|  |  |  |  * NOTE: the idea is NOT to show how the clocks are routed on the chip! | 
					
						
							|  |  |  |  * The ideas is to show dependencies, so a clock higher up in the | 
					
						
							|  |  |  |  * hierarchy has to be on in order for another clock to be on. Now, | 
					
						
							|  |  |  |  * both CPU and DMA can actually be on top of the hierarchy, and that | 
					
						
							|  |  |  |  * is not modeled currently. Instead we have the backbone AMBA bus on | 
					
						
							|  |  |  |  * top. This bus cannot be programmed in any way but conceptually it | 
					
						
							|  |  |  |  * needs to be active for the bridges and devices to transport data. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Please be aware that a few clocks are hw controlled, which mean that | 
					
						
							|  |  |  |  * the hw itself can turn on/off or change the rate of the clock when | 
					
						
							|  |  |  |  * needed! | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  AMBA bus | 
					
						
							|  |  |  |  *  | | 
					
						
							|  |  |  |  *  +- CPU | 
					
						
							| 
									
										
										
										
											2010-09-13 00:35:37 +02:00
										 |  |  |  *  +- FSMC NANDIF NAND Flash interface | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  |  *  +- SEMI Shared Memory interface | 
					
						
							|  |  |  |  *  +- ISP Image Signal Processor (U335 only) | 
					
						
							|  |  |  |  *  +- CDS (U335 only) | 
					
						
							|  |  |  |  *  +- DMA Direct Memory Access Controller | 
					
						
							|  |  |  |  *  +- AAIF APP/ACC Inteface (Mobile Scalable Link, MSL) | 
					
						
							|  |  |  |  *  +- APEX | 
					
						
							|  |  |  |  *  +- VIDEO_ENC AVE2/3 Video Encoder | 
					
						
							|  |  |  |  *  +- XGAM Graphics Accelerator Controller | 
					
						
							|  |  |  |  *  +- AHB | 
					
						
							|  |  |  |  *  | | 
					
						
							|  |  |  |  *  +- ahb:0 AHB Bridge | 
					
						
							|  |  |  |  *  |  | | 
					
						
							|  |  |  |  *  |  +- ahb:1 INTCON Interrupt controller | 
					
						
							|  |  |  |  *  |  +- ahb:3 MSPRO  Memory Stick Pro controller | 
					
						
							|  |  |  |  *  |  +- ahb:4 EMIF   External Memory interface | 
					
						
							|  |  |  |  *  | | 
					
						
							|  |  |  |  *  +- fast:0 FAST bridge | 
					
						
							|  |  |  |  *  |  | | 
					
						
							|  |  |  |  *  |  +- fast:1 MMCSD MMC/SD card reader controller | 
					
						
							|  |  |  |  *  |  +- fast:2 I2S0  PCM I2S channel 0 controller | 
					
						
							|  |  |  |  *  |  +- fast:3 I2S1  PCM I2S channel 1 controller | 
					
						
							|  |  |  |  *  |  +- fast:4 I2C0  I2C channel 0 controller | 
					
						
							|  |  |  |  *  |  +- fast:5 I2C1  I2C channel 1 controller | 
					
						
							|  |  |  |  *  |  +- fast:6 SPI   SPI controller | 
					
						
							|  |  |  |  *  |  +- fast:7 UART1 Secondary UART (U335 only) | 
					
						
							|  |  |  |  *  | | 
					
						
							|  |  |  |  *  +- slow:0 SLOW bridge | 
					
						
							|  |  |  |  *     | | 
					
						
							|  |  |  |  *     +- slow:1 SYSCON (not possible to control) | 
					
						
							|  |  |  |  *     +- slow:2 WDOG Watchdog | 
					
						
							|  |  |  |  *     +- slow:3 UART0 primary UART | 
					
						
							|  |  |  |  *     +- slow:4 TIMER_APP Application timer - used in Linux | 
					
						
							|  |  |  |  *     +- slow:5 KEYPAD controller | 
					
						
							|  |  |  |  *     +- slow:6 GPIO controller | 
					
						
							|  |  |  |  *     +- slow:7 RTC controller | 
					
						
							|  |  |  |  *     +- slow:8 BT Bus Tracer (not used currently) | 
					
						
							|  |  |  |  *     +- slow:9 EH Event Handler (not used currently) | 
					
						
							|  |  |  |  *     +- slow:a TIMER_ACC Access style timer (not used currently) | 
					
						
							|  |  |  |  *     +- slow:b PPM (U335 only, what is that?) | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Reset control functions. We remember if a block has been | 
					
						
							|  |  |  |  * taken out of reset and don't remove the reset assertion again | 
					
						
							|  |  |  |  * and vice versa. Currently we only remove resets so the | 
					
						
							|  |  |  |  * enablement function is defined out. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void syscon_block_reset_enable(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Not all blocks support resetting */ | 
					
						
							|  |  |  | 	if (!clk->res_reg || !clk->res_mask) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_resetreg_lock, iflags); | 
					
						
							|  |  |  | 	val = readw(clk->res_reg); | 
					
						
							|  |  |  | 	val |= clk->res_mask; | 
					
						
							|  |  |  | 	writew(val, clk->res_reg); | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_resetreg_lock, iflags); | 
					
						
							|  |  |  | 	clk->reset = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void syscon_block_reset_disable(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Not all blocks support resetting */ | 
					
						
							|  |  |  | 	if (!clk->res_reg || !clk->res_mask) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_resetreg_lock, iflags); | 
					
						
							|  |  |  | 	val = readw(clk->res_reg); | 
					
						
							|  |  |  | 	val &= ~clk->res_mask; | 
					
						
							|  |  |  | 	writew(val, clk->res_reg); | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_resetreg_lock, iflags); | 
					
						
							|  |  |  | 	clk->reset = false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int __clk_get(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* The MMC and MSPRO clocks need some special set-up */ | 
					
						
							|  |  |  | 	if (!strcmp(clk->name, "MCLK")) { | 
					
						
							|  |  |  | 		/* Set default MMC clock divisor to 18.9 MHz */ | 
					
						
							|  |  |  | 		writew(0x0054U, U300_SYSCON_VBASE + U300_SYSCON_MMF0R); | 
					
						
							|  |  |  | 		val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMCR); | 
					
						
							|  |  |  | 		/* Disable the MMC feedback clock */ | 
					
						
							|  |  |  | 		val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE; | 
					
						
							|  |  |  | 		/* Disable MSPRO frequency */ | 
					
						
							|  |  |  | 		val &= ~U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE; | 
					
						
							|  |  |  | 		writew(val, U300_SYSCON_VBASE + U300_SYSCON_MMCR); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!strcmp(clk->name, "MSPRO")) { | 
					
						
							|  |  |  | 		val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMCR); | 
					
						
							|  |  |  | 		/* Disable the MMC feedback clock */ | 
					
						
							|  |  |  | 		val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE; | 
					
						
							|  |  |  | 		/* Enable MSPRO frequency */ | 
					
						
							|  |  |  | 		val |= U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE; | 
					
						
							|  |  |  | 		writew(val, U300_SYSCON_VBASE + U300_SYSCON_MMCR); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(__clk_get); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __clk_put(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(__clk_put); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void syscon_clk_disable(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Don't touch the hardware controlled clocks */ | 
					
						
							|  |  |  | 	if (clk->hw_ctrld) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | 	writew(clk->clk_val, U300_SYSCON_VBASE + U300_SYSCON_SBCDR); | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void syscon_clk_enable(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Don't touch the hardware controlled clocks */ | 
					
						
							|  |  |  | 	if (clk->hw_ctrld) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | 	writew(clk->clk_val, U300_SYSCON_VBASE + U300_SYSCON_SBCER); | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static u16 syscon_clk_get_rate(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val &= U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK; | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | 	return val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
 | 
					
						
							|  |  |  | static void enable_i2s0_vcxo(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | 	/* Set I2S0 to use the VCXO 26 MHz clock */ | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val |= U300_SYSCON_CCR_TURN_VCXO_ON; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val |= U300_SYSCON_CCR_I2S0_USE_VCXO; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR); | 
					
						
							|  |  |  | 	val |= U300_SYSCON_CEFR_I2S0_CLK_EN; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR); | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void enable_i2s1_vcxo(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | 	/* Set I2S1 to use the VCXO 26 MHz clock */ | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val |= U300_SYSCON_CCR_TURN_VCXO_ON; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val |= U300_SYSCON_CCR_I2S1_USE_VCXO; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR); | 
					
						
							|  |  |  | 	val |= U300_SYSCON_CEFR_I2S1_CLK_EN; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR); | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void disable_i2s0_vcxo(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | 	/* Disable I2S0 use of the VCXO 26 MHz clock */ | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val &= ~U300_SYSCON_CCR_I2S0_USE_VCXO; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							| 
									
										
										
										
											2011-03-30 22:57:33 -03:00
										 |  |  | 	/* Deactivate VCXO if no one else is using VCXO */ | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	if (!(val & U300_SYSCON_CCR_I2S1_USE_VCXO)) | 
					
						
							|  |  |  | 		val &= ~U300_SYSCON_CCR_TURN_VCXO_ON; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR); | 
					
						
							|  |  |  | 	val &= ~U300_SYSCON_CEFR_I2S0_CLK_EN; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR); | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void disable_i2s1_vcxo(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | 	/* Disable I2S1 use of the VCXO 26 MHz clock */ | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val &= ~U300_SYSCON_CCR_I2S1_USE_VCXO; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							| 
									
										
										
										
											2011-03-30 22:57:33 -03:00
										 |  |  | 	/* Deactivate VCXO if no one else is using VCXO */ | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	if (!(val & U300_SYSCON_CCR_I2S0_USE_VCXO)) | 
					
						
							|  |  |  | 		val &= ~U300_SYSCON_CCR_TURN_VCXO_ON; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR); | 
					
						
							|  |  |  | 	val &= ~U300_SYSCON_CEFR_I2S0_CLK_EN; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR); | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* CONFIG_MACH_U300_USE_I2S_AS_MASTER */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void syscon_clk_rate_set_mclk(unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 	u32 reg; | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (rate) { | 
					
						
							|  |  |  | 	case 18900000: | 
					
						
							|  |  |  | 		val = 0x0054; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 20800000: | 
					
						
							|  |  |  | 		val = 0x0044; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 23100000: | 
					
						
							|  |  |  | 		val = 0x0043; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 26000000: | 
					
						
							|  |  |  | 		val = 0x0033; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 29700000: | 
					
						
							|  |  |  | 		val = 0x0032; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 34700000: | 
					
						
							|  |  |  | 		val = 0x0022; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 41600000: | 
					
						
							|  |  |  | 		val = 0x0021; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 52000000: | 
					
						
							|  |  |  | 		val = 0x0011; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 104000000: | 
					
						
							|  |  |  | 		val = 0x0000; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		printk(KERN_ERR "Trying to set MCLK to unknown speed! %ld\n", | 
					
						
							|  |  |  | 		       rate); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | 	reg = readw(U300_SYSCON_VBASE + U300_SYSCON_MMF0R) & | 
					
						
							|  |  |  | 		~U300_SYSCON_MMF0R_MASK; | 
					
						
							|  |  |  | 	writew(reg | val, U300_SYSCON_VBASE + U300_SYSCON_MMF0R); | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void syscon_clk_rate_set_cpuclk(unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (rate) { | 
					
						
							|  |  |  | 	case 13000000: | 
					
						
							|  |  |  | 		val = U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 52000000: | 
					
						
							|  |  |  | 		val = U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 104000000: | 
					
						
							|  |  |  | 		val = U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 208000000: | 
					
						
							|  |  |  | 		val = U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	spin_lock_irqsave(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | 	val |= readw(U300_SYSCON_VBASE + U300_SYSCON_CCR) & | 
					
						
							|  |  |  | 		~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK ; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(syscon_clk_rate_set_cpuclk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void clk_disable(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_irqsave(&clk->lock, iflags); | 
					
						
							|  |  |  | 	if (clk->usecount > 0 && !(--clk->usecount)) { | 
					
						
							|  |  |  | 		/* some blocks lack clocking registers and cannot be disabled */ | 
					
						
							|  |  |  | 		if (clk->disable) | 
					
						
							|  |  |  | 			clk->disable(clk); | 
					
						
							|  |  |  | 		if (likely((u32)clk->parent)) | 
					
						
							|  |  |  | 			clk_disable(clk->parent); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
 | 
					
						
							|  |  |  | 	if (unlikely(!strcmp(clk->name, "I2S0"))) | 
					
						
							|  |  |  | 		disable_i2s0_vcxo(); | 
					
						
							|  |  |  | 	if (unlikely(!strcmp(clk->name, "I2S1"))) | 
					
						
							|  |  |  | 		disable_i2s1_vcxo(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&clk->lock, iflags); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_disable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int clk_enable(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int ret = 0; | 
					
						
							|  |  |  | 	unsigned long iflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock_irqsave(&clk->lock, iflags); | 
					
						
							|  |  |  | 	if (clk->usecount++ == 0) { | 
					
						
							|  |  |  | 		if (likely((u32)clk->parent)) | 
					
						
							|  |  |  | 			ret = clk_enable(clk->parent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (unlikely(ret != 0)) | 
					
						
							|  |  |  | 			clk->usecount--; | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			/* remove reset line (we never enable reset again) */ | 
					
						
							|  |  |  | 			syscon_block_reset_disable(clk); | 
					
						
							|  |  |  | 			/* clocks without enable function are always on */ | 
					
						
							|  |  |  | 			if (clk->enable) | 
					
						
							|  |  |  | 				clk->enable(clk); | 
					
						
							|  |  |  | #ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
 | 
					
						
							|  |  |  | 			if (unlikely(!strcmp(clk->name, "I2S0"))) | 
					
						
							|  |  |  | 				enable_i2s0_vcxo(); | 
					
						
							|  |  |  | 			if (unlikely(!strcmp(clk->name, "I2S1"))) | 
					
						
							|  |  |  | 				enable_i2s1_vcxo(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	spin_unlock_irqrestore(&clk->lock, iflags); | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_enable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Returns the clock rate in Hz */ | 
					
						
							|  |  |  | static unsigned long clk_get_rate_cpuclk(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	val = syscon_clk_get_rate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (val) { | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: | 
					
						
							|  |  |  | 		return 13000000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: | 
					
						
							|  |  |  | 		return 52000000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: | 
					
						
							|  |  |  | 		return 104000000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: | 
					
						
							|  |  |  | 		return 208000000; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return clk->rate; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long clk_get_rate_ahb_clk(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	val = syscon_clk_get_rate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (val) { | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: | 
					
						
							|  |  |  | 		return 6500000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: | 
					
						
							|  |  |  | 		return 26000000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: | 
					
						
							|  |  |  | 		return 52000000; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return clk->rate; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long clk_get_rate_emif_clk(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	val = syscon_clk_get_rate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (val) { | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: | 
					
						
							|  |  |  | 		return 13000000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: | 
					
						
							|  |  |  | 		return 52000000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: | 
					
						
							|  |  |  | 		return 104000000; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return clk->rate; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long clk_get_rate_xgamclk(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	val = syscon_clk_get_rate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (val) { | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: | 
					
						
							|  |  |  | 		return 6500000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: | 
					
						
							|  |  |  | 		return 26000000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: | 
					
						
							|  |  |  | 		return 52000000; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return clk->rate; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long clk_get_rate_mclk(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	val = syscon_clk_get_rate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (val) { | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Here, the 208 MHz PLL gets shut down and the always | 
					
						
							|  |  |  | 		 * on 13 MHz PLL used for RTC etc kicks into use | 
					
						
							|  |  |  | 		 * instead. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		return 13000000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * This clock is under program control. The register is | 
					
						
							|  |  |  | 		 * divided in two nybbles, bit 7-4 gives cycles-1 to count | 
					
						
							|  |  |  | 		 * high, bit 3-0 gives cycles-1 to count low. Distribute | 
					
						
							|  |  |  | 		 * these with no more than 1 cycle difference between | 
					
						
							|  |  |  | 		 * low and high and add low and high to get the actual | 
					
						
							|  |  |  | 		 * divisor. The base PLL is 208 MHz. Writing 0x00 will | 
					
						
							|  |  |  | 		 * divide by 1 and 1 so the highest frequency possible | 
					
						
							|  |  |  | 		 * is 104 MHz. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * e.g. 0x54 => | 
					
						
							|  |  |  | 		 * f = 208 / ((5+1) + (4+1)) = 208 / 11 = 18.9 MHz | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		u16 val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMF0R) & | 
					
						
							|  |  |  | 			U300_SYSCON_MMF0R_MASK; | 
					
						
							|  |  |  | 		switch (val) { | 
					
						
							|  |  |  | 		case 0x0054: | 
					
						
							|  |  |  | 			return 18900000; | 
					
						
							|  |  |  | 		case 0x0044: | 
					
						
							|  |  |  | 			return 20800000; | 
					
						
							|  |  |  | 		case 0x0043: | 
					
						
							|  |  |  | 			return 23100000; | 
					
						
							|  |  |  | 		case 0x0033: | 
					
						
							|  |  |  | 			return 26000000; | 
					
						
							|  |  |  | 		case 0x0032: | 
					
						
							|  |  |  | 			return 29700000; | 
					
						
							|  |  |  | 		case 0x0022: | 
					
						
							|  |  |  | 			return 34700000; | 
					
						
							|  |  |  | 		case 0x0021: | 
					
						
							|  |  |  | 			return 41600000; | 
					
						
							|  |  |  | 		case 0x0011: | 
					
						
							|  |  |  | 			return 52000000; | 
					
						
							|  |  |  | 		case 0x0000: | 
					
						
							|  |  |  | 			return 104000000; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return clk->rate; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long clk_get_rate_i2s_i2c_spi(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	val = syscon_clk_get_rate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (val) { | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: | 
					
						
							|  |  |  | 		return 13000000; | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: | 
					
						
							|  |  |  | 	case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: | 
					
						
							|  |  |  | 		return 26000000; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return clk->rate; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | unsigned long clk_get_rate(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (clk->get_rate) | 
					
						
							|  |  |  | 		return clk->get_rate(clk); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return clk->rate; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_get_rate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long clk_round_rate_mclk(struct clk *clk, unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 18900000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 18900000; | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 20800000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 20800000; | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 23100000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 23100000; | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 26000000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 26000000; | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 29700000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 29700000; | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 34700000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 34700000; | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 41600000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 41600000; | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 52000000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 52000000; | 
					
						
							|  |  |  | 	return -EINVAL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long clk_round_rate_cpuclk(struct clk *clk, unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 13000000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 13000000; | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 52000000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 52000000; | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 104000000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 104000000; | 
					
						
							| 
									
										
										
										
											2010-02-24 21:49:53 +01:00
										 |  |  | 	if (rate <= 208000000) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 		return 208000000; | 
					
						
							|  |  |  | 	return -EINVAL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * This adjusts a requested rate to the closest exact rate | 
					
						
							|  |  |  |  * a certain clock can provide. For a fixed clock it's | 
					
						
							|  |  |  |  * mostly clk->rate. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | long clk_round_rate(struct clk *clk, unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-30 22:57:33 -03:00
										 |  |  | 	/* TODO: get appropriate switches for EMIFCLK, AHBCLK and MCLK */ | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	/* Else default to fixed value */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (clk->round_rate) { | 
					
						
							|  |  |  | 		return (long) clk->round_rate(clk, rate); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		printk(KERN_ERR "clock: Failed to round rate of %s\n", | 
					
						
							|  |  |  | 		       clk->name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return (long) clk->rate; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_round_rate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int clk_set_rate_mclk(struct clk *clk, unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	syscon_clk_rate_set_mclk(clk_round_rate(clk, rate)); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int clk_set_rate_cpuclk(struct clk *clk, unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	syscon_clk_rate_set_cpuclk(clk_round_rate(clk, rate)); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int clk_set_rate(struct clk *clk, unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* TODO: set for EMIFCLK and AHBCLK */ | 
					
						
							|  |  |  | 	/* Else assume the clock is fixed and fail */ | 
					
						
							|  |  |  | 	if (clk->set_rate) { | 
					
						
							|  |  |  | 		return clk->set_rate(clk, rate); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		printk(KERN_ERR "clock: Failed to set %s to %ld hz\n", | 
					
						
							|  |  |  | 		       clk->name, rate); | 
					
						
							| 
									
										
										
										
											2009-05-31 15:08:11 +01:00
										 |  |  | 		return -EINVAL; | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_set_rate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Clock definitions. The clock parents are set to respective | 
					
						
							|  |  |  |  * bridge and the clock framework makes sure that the clocks have | 
					
						
							|  |  |  |  * parents activated and are brought out of reset when in use. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Clocks that have hw_ctrld = true are hw controlled, and the hw | 
					
						
							|  |  |  |  * can by itself turn these clocks on and off. | 
					
						
							|  |  |  |  * So in other words, we don't really have to care about them. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk amba_clk = { | 
					
						
							|  |  |  | 	.name	    = "AMBA", | 
					
						
							|  |  |  | 	.rate	    = 52000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = false, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(amba_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * These blocks are connected directly to the AMBA bus | 
					
						
							|  |  |  |  * with no bridge. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk cpu_clk = { | 
					
						
							|  |  |  | 	.name	    = "CPU", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate	    = 208000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_CPU_RESET_EN, | 
					
						
							|  |  |  | 	.set_rate   = clk_set_rate_cpuclk, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_cpuclk, | 
					
						
							|  |  |  | 	.round_rate = clk_round_rate_cpuclk, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(cpu_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk nandif_clk = { | 
					
						
							| 
									
										
										
										
											2010-09-13 00:35:37 +02:00
										 |  |  | 	.name       = "FSMC", | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_NANDIF_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_NANDIF_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(nandif_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk semi_clk = { | 
					
						
							|  |  |  | 	.name       = "SEMI", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate       = 0, /* FIXME */ | 
					
						
							|  |  |  | 	/* It is not possible to reset SEMI */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = false, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_SEMI_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(semi_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_MACH_U300_BS335
 | 
					
						
							|  |  |  | static struct clk isp_clk = { | 
					
						
							|  |  |  | 	.name	    = "ISP", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate	    = 0, /* FIXME */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_ISP_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_ISP_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(isp_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk cds_clk = { | 
					
						
							|  |  |  | 	.name	    = "CDS", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate	    = 0, /* FIXME */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_CDS_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_CDS_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(cds_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk dma_clk = { | 
					
						
							|  |  |  | 	.name       = "DMA", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate       = 52000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_DMAC_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_DMAC_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(dma_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk aaif_clk = { | 
					
						
							|  |  |  | 	.name       = "AAIF", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate       = 52000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_AAIF_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_AAIF_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(aaif_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk apex_clk = { | 
					
						
							|  |  |  | 	.name       = "APEX", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate       = 0, /* FIXME */ | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_APEX_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_APEX_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(apex_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk video_enc_clk = { | 
					
						
							|  |  |  | 	.name       = "VIDEO_ENC", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate       = 208000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = false, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	/* This has XGAM in the name but refers to the video encoder */ | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(video_enc_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk xgam_clk = { | 
					
						
							|  |  |  | 	.name       = "XGAMCLK", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate       = 52000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_XGAM_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_XGAM_CLK_EN, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_xgamclk, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(xgam_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This clock is used to activate the video encoder */ | 
					
						
							|  |  |  | static struct clk ahb_clk = { | 
					
						
							|  |  |  | 	.name	    = "AHB", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate	    = 52000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, /* This one is set to false due to HW bug */ | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_AHB_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_AHB_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_ahb_clk, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(ahb_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Clocks on the AHB bridge | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk ahb_subsys_clk = { | 
					
						
							|  |  |  | 	.name	    = "AHB_SUBSYS", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate	    = 52000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = false, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_ahb_clk, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(ahb_subsys_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk intcon_clk = { | 
					
						
							|  |  |  | 	.name	    = "INTCON", | 
					
						
							|  |  |  | 	.parent	    = &ahb_subsys_clk, | 
					
						
							|  |  |  | 	.rate	    = 52000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_INTCON_RESET_EN, | 
					
						
							|  |  |  | 	/* INTCON can be reset but not clock-gated */ | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(intcon_clk.lock), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk mspro_clk = { | 
					
						
							|  |  |  | 	.name       = "MSPRO", | 
					
						
							|  |  |  | 	.parent	    = &ahb_subsys_clk, | 
					
						
							|  |  |  | 	.rate       = 0, /* FIXME */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_MSPRO_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_MSPRO_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(mspro_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk emif_clk = { | 
					
						
							|  |  |  | 	.name	    = "EMIF", | 
					
						
							|  |  |  | 	.parent	    = &ahb_subsys_clk, | 
					
						
							|  |  |  | 	.rate	    = 104000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RRR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RRR_EMIF_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_EMIF_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_emif_clk, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(emif_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Clocks on the FAST bridge | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static struct clk fast_clk = { | 
					
						
							|  |  |  | 	.name	    = "FAST_BRIDGE", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate	    = 13000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RFR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(fast_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * The MMCI apb_pclk is hardwired to the same terminal as the | 
					
						
							|  |  |  |  * external MCI clock. Thus this will be referenced twice. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | static struct clk mmcsd_clk = { | 
					
						
							|  |  |  | 	.name       = "MCLK", | 
					
						
							|  |  |  | 	.parent	    = &fast_clk, | 
					
						
							|  |  |  | 	.rate       = 18900000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RFR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RFR_MMC_RESET_ENABLE, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_MMC_CLK_EN, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_mclk, | 
					
						
							|  |  |  | 	.set_rate   = clk_set_rate_mclk, | 
					
						
							|  |  |  | 	.round_rate = clk_round_rate_mclk, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(mmcsd_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk i2s0_clk = { | 
					
						
							|  |  |  | 	.name       = "i2s0", | 
					
						
							|  |  |  | 	.parent	    = &fast_clk, | 
					
						
							|  |  |  | 	.rate       = 26000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RFR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_I2S0_CORE_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_i2s_i2c_spi, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(i2s0_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk i2s1_clk = { | 
					
						
							|  |  |  | 	.name       = "i2s1", | 
					
						
							|  |  |  | 	.parent	    = &fast_clk, | 
					
						
							|  |  |  | 	.rate       = 26000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RFR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_I2S1_CORE_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_i2s_i2c_spi, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(i2s1_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk i2c0_clk = { | 
					
						
							|  |  |  | 	.name       = "I2C0", | 
					
						
							|  |  |  | 	.parent	    = &fast_clk, | 
					
						
							|  |  |  | 	.rate       = 26000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RFR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RFR_I2C0_RESET_ENABLE, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_I2C0_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_i2s_i2c_spi, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(i2c0_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk i2c1_clk = { | 
					
						
							|  |  |  | 	.name       = "I2C1", | 
					
						
							|  |  |  | 	.parent	    = &fast_clk, | 
					
						
							|  |  |  | 	.rate       = 26000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RFR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RFR_I2C1_RESET_ENABLE, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_I2C1_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_i2s_i2c_spi, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(i2c1_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * The SPI apb_pclk is hardwired to the same terminal as the | 
					
						
							|  |  |  |  * external SPI clock. Thus this will be referenced twice. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | static struct clk spi_clk = { | 
					
						
							|  |  |  | 	.name       = "SPI", | 
					
						
							|  |  |  | 	.parent	    = &fast_clk, | 
					
						
							|  |  |  | 	.rate       = 26000000, /* this varies! */ | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RFR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RFR_SPI_RESET_ENABLE, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_SPI_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							|  |  |  | 	.get_rate   = clk_get_rate_i2s_i2c_spi, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(spi_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_MACH_U300_BS335
 | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | static struct clk uart1_pclk = { | 
					
						
							|  |  |  | 	.name	    = "UART1_PCLK", | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	.parent	    = &fast_clk, | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RFR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RFR_UART1_RESET_ENABLE, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_UART1_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(uart1_pclk.lock), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This one is hardwired to PLL13 */ | 
					
						
							|  |  |  | static struct clk uart1_clk = { | 
					
						
							|  |  |  | 	.name	    = "UART1_CLK", | 
					
						
							|  |  |  | 	.rate	    = 13000000, | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(uart1_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Clocks on the SLOW bridge | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static struct clk slow_clk = { | 
					
						
							|  |  |  | 	.name	    = "SLOW_BRIDGE", | 
					
						
							|  |  |  | 	.parent	    = &amba_clk, | 
					
						
							|  |  |  | 	.rate	    = 13000000, | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RSR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(slow_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* TODO: implement SYSCON clock? */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk wdog_clk = { | 
					
						
							|  |  |  | 	.name	    = "WDOG", | 
					
						
							|  |  |  | 	.parent	    = &slow_clk, | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.rate	    = 32768, | 
					
						
							|  |  |  | 	.reset	    = false, | 
					
						
							|  |  |  | 	/* This is always on, cannot be enabled/disabled or reset */ | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(wdog_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | static struct clk uart0_pclk = { | 
					
						
							|  |  |  | 	.name	    = "UART0_PCLK", | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	.parent	    = &slow_clk, | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RSR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RSR_UART_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_UART_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(uart0_pclk.lock), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This one is hardwired to PLL13 */ | 
					
						
							|  |  |  | static struct clk uart0_clk = { | 
					
						
							|  |  |  | 	.name	    = "UART0_CLK", | 
					
						
							|  |  |  | 	.parent	    = &slow_clk, | 
					
						
							|  |  |  | 	.rate	    = 13000000, | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(uart0_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk keypad_clk = { | 
					
						
							|  |  |  | 	.name       = "KEYPAD", | 
					
						
							|  |  |  | 	.parent	    = &slow_clk, | 
					
						
							|  |  |  | 	.rate       = 32768, | 
					
						
							|  |  |  | 	.hw_ctrld   = false, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RSR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RSR_KEYPAD_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_KEYPAD_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(keypad_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk gpio_clk = { | 
					
						
							|  |  |  | 	.name       = "GPIO", | 
					
						
							|  |  |  | 	.parent	    = &slow_clk, | 
					
						
							|  |  |  | 	.rate       = 13000000, | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RSR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RSR_GPIO_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_GPIO_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(gpio_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk rtc_clk = { | 
					
						
							|  |  |  | 	.name	    = "RTC", | 
					
						
							|  |  |  | 	.parent	    = &slow_clk, | 
					
						
							|  |  |  | 	.rate	    = 32768, | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RSR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RSR_RTC_RESET_EN, | 
					
						
							|  |  |  | 	/* This clock is always on, cannot be enabled/disabled */ | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(rtc_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk bustr_clk = { | 
					
						
							|  |  |  | 	.name       = "BUSTR", | 
					
						
							|  |  |  | 	.parent	    = &slow_clk, | 
					
						
							|  |  |  | 	.rate       = 13000000, | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RSR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RSR_BTR_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_BTR_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(bustr_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk evhist_clk = { | 
					
						
							|  |  |  | 	.name       = "EVHIST", | 
					
						
							|  |  |  | 	.parent	    = &slow_clk, | 
					
						
							|  |  |  | 	.rate       = 13000000, | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RSR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RSR_EH_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_EH_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(evhist_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk timer_clk = { | 
					
						
							|  |  |  | 	.name       = "TIMER", | 
					
						
							|  |  |  | 	.parent	    = &slow_clk, | 
					
						
							|  |  |  | 	.rate       = 13000000, | 
					
						
							|  |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RSR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RSR_ACC_TMR_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_ACC_TMR_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(timer_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-05 07:59:54 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * There is a binary divider in the hardware that divides | 
					
						
							|  |  |  |  * the 13MHz PLL by 13 down to 1 MHz. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | static struct clk app_timer_clk = { | 
					
						
							|  |  |  | 	.name       = "TIMER_APP", | 
					
						
							|  |  |  | 	.parent	    = &slow_clk, | 
					
						
							| 
									
										
										
										
											2010-08-05 07:59:54 +01:00
										 |  |  | 	.rate       = 1000000, | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	.hw_ctrld   = true, | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RSR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RSR_APP_TMR_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_APP_TMR_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(app_timer_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_MACH_U300_BS335
 | 
					
						
							|  |  |  | static struct clk ppm_clk = { | 
					
						
							|  |  |  | 	.name	    = "PPM", | 
					
						
							|  |  |  | 	.parent	    = &slow_clk, | 
					
						
							|  |  |  | 	.rate	    = 0, /* FIXME */ | 
					
						
							|  |  |  | 	.hw_ctrld   = true, /* TODO: Look up if it is hw ctrld or not */ | 
					
						
							|  |  |  | 	.reset	    = true, | 
					
						
							|  |  |  | 	.res_reg    = U300_SYSCON_VBASE + U300_SYSCON_RSR, | 
					
						
							|  |  |  | 	.res_mask   = U300_SYSCON_RSR_PPM_RESET_EN, | 
					
						
							|  |  |  | 	.clk_val    = U300_SYSCON_SBCER_PPM_CLK_EN, | 
					
						
							|  |  |  | 	.enable     = syscon_clk_enable, | 
					
						
							|  |  |  | 	.disable    = syscon_clk_disable, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	.lock       = __SPIN_LOCK_UNLOCKED(ppm_clk.lock), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define DEF_LOOKUP(devid, clkref)		\
 | 
					
						
							|  |  |  | 	{					\ | 
					
						
							|  |  |  | 	.dev_id = devid,			\ | 
					
						
							|  |  |  | 	.clk = clkref,				\ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | #define DEF_LOOKUP_CON(devid, conid, clkref)	\
 | 
					
						
							|  |  |  | 	{					\ | 
					
						
							|  |  |  | 	.dev_id = devid,			\ | 
					
						
							|  |  |  | 	.con_id = conid,			\ | 
					
						
							|  |  |  | 	.clk = clkref,				\ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Here we only define clocks that are meaningful to | 
					
						
							|  |  |  |  * look up through clockdevice. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static struct clk_lookup lookups[] = { | 
					
						
							|  |  |  | 	/* Connected directly to the AMBA bus */ | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("amba",      &amba_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("cpu",       &cpu_clk), | 
					
						
							| 
									
										
										
										
											2010-09-13 00:35:37 +02:00
										 |  |  | 	DEF_LOOKUP("fsmc-nand", &nandif_clk), | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("semi",      &semi_clk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | #ifdef CONFIG_MACH_U300_BS335
 | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("isp",       &isp_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("cds",       &cds_clk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("dma",       &dma_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("msl",       &aaif_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("apex",      &apex_clk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	DEF_LOOKUP("video_enc", &video_enc_clk), | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("xgam",      &xgam_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("ahb",       &ahb_clk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	/* AHB bridge clocks */ | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("ahb_subsys", &ahb_subsys_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("intcon",    &intcon_clk), | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	DEF_LOOKUP_CON("intcon", "apb_pclk", &intcon_clk), | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("mspro",     &mspro_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("pl172",     &emif_clk), | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	DEF_LOOKUP_CON("pl172", "apb_pclk", &emif_clk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	/* FAST bridge clocks */ | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("fast",      &fast_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("mmci",      &mmcsd_clk), | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	DEF_LOOKUP_CON("mmci", "apb_pclk", &mmcsd_clk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The .0 and .1 identifiers on these comes from the platform device | 
					
						
							|  |  |  | 	 * .id field and are assigned when the platform devices are registered. | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("i2s.0",     &i2s0_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("i2s.1",     &i2s1_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("stu300.0",  &i2c0_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("stu300.1",  &i2c1_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("pl022",     &spi_clk), | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	DEF_LOOKUP_CON("pl022", "apb_pclk", &spi_clk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | #ifdef CONFIG_MACH_U300_BS335
 | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("uart1",     &uart1_clk), | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	DEF_LOOKUP_CON("uart1", "apb_pclk", &uart1_pclk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	/* SLOW bridge clocks */ | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("slow",      &slow_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("coh901327_wdog",      &wdog_clk), | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	DEF_LOOKUP("uart0",     &uart0_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP_CON("uart0", "apb_pclk", &uart0_pclk), | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("apptimer",  &app_timer_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("coh901461-keypad",    &keypad_clk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	DEF_LOOKUP("u300-gpio", &gpio_clk), | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("rtc-coh901331",      &rtc_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("bustr",     &bustr_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("evhist",    &evhist_clk), | 
					
						
							|  |  |  | 	DEF_LOOKUP("timer",     &timer_clk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | #ifdef CONFIG_MACH_U300_BS335
 | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 	DEF_LOOKUP("ppm",       &ppm_clk), | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void __init clk_register(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* Register the lookups */ | 
					
						
							| 
									
										
										
										
											2010-01-12 12:28:00 +00:00
										 |  |  | 	clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * The following makes it possible to view the status (especially | 
					
						
							|  |  |  |  * reference count and reset status) for the clocks in the platform | 
					
						
							|  |  |  |  * by looking into the special file <debugfs>/u300_clocks | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* A list of all clocks in the platform */ | 
					
						
							|  |  |  | static struct clk *clks[] = { | 
					
						
							|  |  |  | 	/* Top node clock for the AMBA bus */ | 
					
						
							|  |  |  | 	&amba_clk, | 
					
						
							|  |  |  | 	/* Connected directly to the AMBA bus */ | 
					
						
							|  |  |  | 	&cpu_clk, | 
					
						
							|  |  |  | 	&nandif_clk, | 
					
						
							|  |  |  | 	&semi_clk, | 
					
						
							|  |  |  | #ifdef CONFIG_MACH_U300_BS335
 | 
					
						
							|  |  |  | 	&isp_clk, | 
					
						
							|  |  |  | 	&cds_clk, | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	&dma_clk, | 
					
						
							|  |  |  | 	&aaif_clk, | 
					
						
							|  |  |  | 	&apex_clk, | 
					
						
							|  |  |  | 	&video_enc_clk, | 
					
						
							|  |  |  | 	&xgam_clk, | 
					
						
							|  |  |  | 	&ahb_clk, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* AHB bridge clocks */ | 
					
						
							|  |  |  | 	&ahb_subsys_clk, | 
					
						
							|  |  |  | 	&intcon_clk, | 
					
						
							|  |  |  | 	&mspro_clk, | 
					
						
							|  |  |  | 	&emif_clk, | 
					
						
							|  |  |  | 	/* FAST bridge clocks */ | 
					
						
							|  |  |  | 	&fast_clk, | 
					
						
							|  |  |  | 	&mmcsd_clk, | 
					
						
							|  |  |  | 	&i2s0_clk, | 
					
						
							|  |  |  | 	&i2s1_clk, | 
					
						
							|  |  |  | 	&i2c0_clk, | 
					
						
							|  |  |  | 	&i2c1_clk, | 
					
						
							|  |  |  | 	&spi_clk, | 
					
						
							|  |  |  | #ifdef CONFIG_MACH_U300_BS335
 | 
					
						
							|  |  |  | 	&uart1_clk, | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	&uart1_pclk, | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	/* SLOW bridge clocks */ | 
					
						
							|  |  |  | 	&slow_clk, | 
					
						
							|  |  |  | 	&wdog_clk, | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	&uart0_clk, | 
					
						
							|  |  |  | 	&uart0_pclk, | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 	&app_timer_clk, | 
					
						
							|  |  |  | 	&keypad_clk, | 
					
						
							|  |  |  | 	&gpio_clk, | 
					
						
							|  |  |  | 	&rtc_clk, | 
					
						
							|  |  |  | 	&bustr_clk, | 
					
						
							|  |  |  | 	&evhist_clk, | 
					
						
							|  |  |  | 	&timer_clk, | 
					
						
							|  |  |  | #ifdef CONFIG_MACH_U300_BS335
 | 
					
						
							|  |  |  | 	&ppm_clk, | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int u300_clocks_show(struct seq_file *s, void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct clk *clk; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	seq_printf(s, "CLOCK           DEVICE          RESET STATE\t" \ | 
					
						
							|  |  |  | 		   "ACTIVE\tUSERS\tHW CTRL FREQ\n"); | 
					
						
							|  |  |  | 	seq_printf(s, "---------------------------------------------" \ | 
					
						
							|  |  |  | 		   "-----------------------------------------\n"); | 
					
						
							|  |  |  | 	for (i = 0; i < ARRAY_SIZE(clks); i++) { | 
					
						
							|  |  |  | 		clk = clks[i]; | 
					
						
							|  |  |  | 		if (clk != ERR_PTR(-ENOENT)) { | 
					
						
							|  |  |  | 			/* Format clock and device name nicely */ | 
					
						
							|  |  |  | 			char cdp[33]; | 
					
						
							|  |  |  | 			int chars; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			chars = snprintf(&cdp[0], 17, "%s", clk->name); | 
					
						
							|  |  |  | 			while (chars < 16) { | 
					
						
							|  |  |  | 				cdp[chars] = ' '; | 
					
						
							|  |  |  | 				chars++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			chars = snprintf(&cdp[16], 17, "%s", clk->dev ? | 
					
						
							|  |  |  | 					 dev_name(clk->dev) : "N/A"); | 
					
						
							|  |  |  | 			while (chars < 16) { | 
					
						
							|  |  |  | 				cdp[chars+16] = ' '; | 
					
						
							|  |  |  | 				chars++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			cdp[32] = '\0'; | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 			if (clk->get_rate || clk->rate != 0) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 				seq_printf(s, | 
					
						
							|  |  |  | 					   "%s%s\t%s\t%d\t%s\t%lu Hz\n", | 
					
						
							|  |  |  | 					   &cdp[0], | 
					
						
							|  |  |  | 					   clk->reset ? | 
					
						
							|  |  |  | 					   "ASSERTED" : "RELEASED", | 
					
						
							|  |  |  | 					   clk->usecount ? "ON" : "OFF", | 
					
						
							|  |  |  | 					   clk->usecount, | 
					
						
							|  |  |  | 					   clk->hw_ctrld  ? "YES" : "NO ", | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 					   clk_get_rate(clk)); | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 			else | 
					
						
							|  |  |  | 				seq_printf(s, | 
					
						
							|  |  |  | 					   "%s%s\t%s\t%d\t%s\t" \ | 
					
						
							|  |  |  | 					   "(unknown rate)\n", | 
					
						
							|  |  |  | 					   &cdp[0], | 
					
						
							|  |  |  | 					   clk->reset ? | 
					
						
							|  |  |  | 					   "ASSERTED" : "RELEASED", | 
					
						
							|  |  |  | 					   clk->usecount ? "ON" : "OFF", | 
					
						
							|  |  |  | 					   clk->usecount, | 
					
						
							|  |  |  | 					   clk->hw_ctrld  ? "YES" : "NO "); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int u300_clocks_open(struct inode *inode, struct file *file) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return single_open(file, u300_clocks_show, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct file_operations u300_clocks_operations = { | 
					
						
							|  |  |  | 	.open		= u300_clocks_open, | 
					
						
							|  |  |  | 	.read		= seq_read, | 
					
						
							|  |  |  | 	.llseek		= seq_lseek, | 
					
						
							|  |  |  | 	.release	= single_release, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | static int __init init_clk_read_debugfs(void) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* Expose a simple debugfs interface to view all clocks */ | 
					
						
							|  |  |  | 	(void) debugfs_create_file("u300_clocks", S_IFREG | S_IRUGO, | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | 				   NULL, NULL, | 
					
						
							|  |  |  | 				   &u300_clocks_operations); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-07-02 00:27:57 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This needs to come in after the core_initcall() for the | 
					
						
							|  |  |  |  * overall clocks, because debugfs is not available until | 
					
						
							|  |  |  |  * the subsystems come up. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | module_init(init_clk_read_debugfs); | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | int __init u300_clock_init(void) | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	u16 val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * FIXME: shall all this powermanagement stuff really live here??? | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Set system to run at PLL208, max performance, a known state. */ | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 
					
						
							|  |  |  | 	/* Wait for the PLL208 to lock if not locked in yet */ | 
					
						
							|  |  |  | 	while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) & | 
					
						
							|  |  |  | 		 U300_SYSCON_CSR_PLL208_LOCK_IND)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Power management enable */ | 
					
						
							|  |  |  | 	val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR); | 
					
						
							|  |  |  | 	val |= U300_SYSCON_PMCR_PWR_MGNT_ENABLE; | 
					
						
							|  |  |  | 	writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	clk_register(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Some of these may be on when we boot the system so make sure they | 
					
						
							|  |  |  | 	 * are turned OFF. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	syscon_block_reset_enable(&timer_clk); | 
					
						
							|  |  |  | 	timer_clk.disable(&timer_clk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * These shall be turned on by default when we boot the system | 
					
						
							|  |  |  | 	 * so make sure they are ON. (Adding CPU here is a bit too much.) | 
					
						
							|  |  |  | 	 * These clocks will be claimed by drivers later. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	syscon_block_reset_disable(&semi_clk); | 
					
						
							|  |  |  | 	syscon_block_reset_disable(&emif_clk); | 
					
						
							| 
									
										
										
										
											2010-08-05 07:58:13 +01:00
										 |  |  | 	clk_enable(&semi_clk); | 
					
						
							|  |  |  | 	clk_enable(&emif_clk); | 
					
						
							| 
									
										
										
										
											2009-04-23 10:21:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } |