| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * linux/arch/unicore32/kernel/clock.c | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Code specific to PKUnity SoC and UniCore ISA | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn> | 
					
						
							|  |  |  |  *	Copyright (C) 2001-2010 Guan Xuetao | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License version 2 as | 
					
						
							|  |  |  |  * published by the Free Software Foundation. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <linux/module.h>
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/device.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/delay.h>
 | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | #include <linux/io.h>
 | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <mach/hardware.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Very simple clock implementation | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | struct clk { | 
					
						
							|  |  |  | 	struct list_head	node; | 
					
						
							|  |  |  | 	unsigned long		rate; | 
					
						
							|  |  |  | 	const char		*name; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk clk_ost_clk = { | 
					
						
							|  |  |  | 	.name		= "OST_CLK", | 
					
						
							|  |  |  | 	.rate		= CLOCK_TICK_RATE, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk clk_mclk_clk = { | 
					
						
							|  |  |  | 	.name		= "MAIN_CLK", | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk clk_bclk32_clk = { | 
					
						
							|  |  |  | 	.name		= "BUS32_CLK", | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk clk_ddr_clk = { | 
					
						
							|  |  |  | 	.name		= "DDR_CLK", | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk clk_vga_clk = { | 
					
						
							|  |  |  | 	.name		= "VGA_CLK", | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static LIST_HEAD(clocks); | 
					
						
							|  |  |  | static DEFINE_MUTEX(clocks_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct clk *clk_get(struct device *dev, const char *id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct clk *p, *clk = ERR_PTR(-ENOENT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mutex_lock(&clocks_mutex); | 
					
						
							|  |  |  | 	list_for_each_entry(p, &clocks, node) { | 
					
						
							|  |  |  | 		if (strcmp(id, p->name) == 0) { | 
					
						
							|  |  |  | 			clk = p; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mutex_unlock(&clocks_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return clk; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_get); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void clk_put(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_put); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int clk_enable(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_enable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void clk_disable(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_disable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | unsigned long clk_get_rate(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return clk->rate; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_get_rate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct { | 
					
						
							|  |  |  | 	unsigned long rate; | 
					
						
							|  |  |  | 	unsigned long cfg; | 
					
						
							|  |  |  | 	unsigned long div; | 
					
						
							|  |  |  | } vga_clk_table[] = { | 
					
						
							|  |  |  | 	{.rate =  25175000, .cfg = 0x00002001, .div = 0x9}, | 
					
						
							|  |  |  | 	{.rate =  31500000, .cfg = 0x00002001, .div = 0x7}, | 
					
						
							|  |  |  | 	{.rate =  40000000, .cfg = 0x00003801, .div = 0x9}, | 
					
						
							|  |  |  | 	{.rate =  49500000, .cfg = 0x00003801, .div = 0x7}, | 
					
						
							|  |  |  | 	{.rate =  65000000, .cfg = 0x00002c01, .div = 0x4}, | 
					
						
							|  |  |  | 	{.rate =  78750000, .cfg = 0x00002400, .div = 0x7}, | 
					
						
							|  |  |  | 	{.rate = 108000000, .cfg = 0x00002c01, .div = 0x2}, | 
					
						
							|  |  |  | 	{.rate = 106500000, .cfg = 0x00003c01, .div = 0x3}, | 
					
						
							|  |  |  | 	{.rate =  50650000, .cfg = 0x00106400, .div = 0x9}, | 
					
						
							|  |  |  | 	{.rate =  61500000, .cfg = 0x00106400, .div = 0xa}, | 
					
						
							|  |  |  | 	{.rate =  85500000, .cfg = 0x00002800, .div = 0x6}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct { | 
					
						
							|  |  |  | 	unsigned long mrate; | 
					
						
							|  |  |  | 	unsigned long prate; | 
					
						
							|  |  |  | } mclk_clk_table[] = { | 
					
						
							|  |  |  | 	{.mrate = 500000000, .prate = 0x00109801}, | 
					
						
							|  |  |  | 	{.mrate = 525000000, .prate = 0x00104C00}, | 
					
						
							|  |  |  | 	{.mrate = 550000000, .prate = 0x00105000}, | 
					
						
							|  |  |  | 	{.mrate = 575000000, .prate = 0x00105400}, | 
					
						
							|  |  |  | 	{.mrate = 600000000, .prate = 0x00105800}, | 
					
						
							|  |  |  | 	{.mrate = 625000000, .prate = 0x00105C00}, | 
					
						
							|  |  |  | 	{.mrate = 650000000, .prate = 0x00106000}, | 
					
						
							|  |  |  | 	{.mrate = 675000000, .prate = 0x00106400}, | 
					
						
							|  |  |  | 	{.mrate = 700000000, .prate = 0x00106800}, | 
					
						
							|  |  |  | 	{.mrate = 725000000, .prate = 0x00106C00}, | 
					
						
							|  |  |  | 	{.mrate = 750000000, .prate = 0x00107000}, | 
					
						
							|  |  |  | 	{.mrate = 775000000, .prate = 0x00107400}, | 
					
						
							|  |  |  | 	{.mrate = 800000000, .prate = 0x00107800}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int clk_set_rate(struct clk *clk, unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (clk == &clk_vga_clk) { | 
					
						
							|  |  |  | 		unsigned long pll_vgacfg, pll_vgadiv; | 
					
						
							|  |  |  | 		int ret, i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* lookup vga_clk_table */ | 
					
						
							|  |  |  | 		ret = -EINVAL; | 
					
						
							|  |  |  | 		for (i = 0; i < ARRAY_SIZE(vga_clk_table); i++) { | 
					
						
							|  |  |  | 			if (rate == vga_clk_table[i].rate) { | 
					
						
							|  |  |  | 				pll_vgacfg = vga_clk_table[i].cfg; | 
					
						
							|  |  |  | 				pll_vgadiv = vga_clk_table[i].div; | 
					
						
							|  |  |  | 				ret = 0; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (ret) | 
					
						
							|  |  |  | 			return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 		if (readl(PM_PLLVGACFG) == pll_vgacfg) | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 			return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* set pll vga cfg reg. */ | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 		writel(pll_vgacfg, PM_PLLVGACFG); | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 		writel(PM_PMCR_CFBVGA, PM_PMCR); | 
					
						
							|  |  |  | 		while ((readl(PM_PLLDFCDONE) & PM_PLLDFCDONE_VGADFC) | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 				!= PM_PLLDFCDONE_VGADFC) | 
					
						
							|  |  |  | 			udelay(100); /* about 1ms */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* set div cfg reg. */ | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 		writel(readl(PM_PCGR) | PM_PCGR_VGACLK, PM_PCGR); | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 		writel((readl(PM_DIVCFG) & ~PM_DIVCFG_VGACLK_MASK) | 
					
						
							|  |  |  | 				| PM_DIVCFG_VGACLK(pll_vgadiv), PM_DIVCFG); | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 		writel(readl(PM_SWRESET) | PM_SWRESET_VGADIV, PM_SWRESET); | 
					
						
							|  |  |  | 		while ((readl(PM_SWRESET) & PM_SWRESET_VGADIV) | 
					
						
							|  |  |  | 				== PM_SWRESET_VGADIV) | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 			udelay(100); /* 65536 bclk32, about 320us */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 		writel(readl(PM_PCGR) & ~PM_PCGR_VGACLK, PM_PCGR); | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | #ifdef CONFIG_CPU_FREQ
 | 
					
						
							|  |  |  | 	if (clk == &clk_mclk_clk) { | 
					
						
							|  |  |  | 		u32 pll_rate, divstatus = PM_DIVSTATUS; | 
					
						
							|  |  |  | 		int ret, i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* lookup mclk_clk_table */ | 
					
						
							|  |  |  | 		ret = -EINVAL; | 
					
						
							|  |  |  | 		for (i = 0; i < ARRAY_SIZE(mclk_clk_table); i++) { | 
					
						
							|  |  |  | 			if (rate == mclk_clk_table[i].mrate) { | 
					
						
							|  |  |  | 				pll_rate = mclk_clk_table[i].prate; | 
					
						
							|  |  |  | 				clk_mclk_clk.rate = mclk_clk_table[i].mrate; | 
					
						
							|  |  |  | 				ret = 0; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (ret) | 
					
						
							|  |  |  | 			return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (clk_mclk_clk.rate) | 
					
						
							|  |  |  | 			clk_bclk32_clk.rate = clk_mclk_clk.rate | 
					
						
							|  |  |  | 				/ (((divstatus & 0x0000f000) >> 12) + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* set pll sys cfg reg. */ | 
					
						
							|  |  |  | 		PM_PLLSYSCFG = pll_rate; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		PM_PMCR = PM_PMCR_CFBSYS; | 
					
						
							|  |  |  | 		while ((PM_PLLDFCDONE & PM_PLLDFCDONE_SYSDFC) | 
					
						
							|  |  |  | 				!= PM_PLLDFCDONE_SYSDFC) | 
					
						
							|  |  |  | 			udelay(100); | 
					
						
							|  |  |  | 			/* about 1ms */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_set_rate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int clk_register(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	mutex_lock(&clocks_mutex); | 
					
						
							|  |  |  | 	list_add(&clk->node, &clocks); | 
					
						
							|  |  |  | 	mutex_unlock(&clocks_mutex); | 
					
						
							|  |  |  | 	printk(KERN_DEFAULT "PKUnity PM: %s %lu.%02luM\n", clk->name, | 
					
						
							|  |  |  | 		(clk->rate)/1000000, (clk->rate)/10000 % 100); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_register); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void clk_unregister(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	mutex_lock(&clocks_mutex); | 
					
						
							|  |  |  | 	list_del(&clk->node); | 
					
						
							|  |  |  | 	mutex_unlock(&clocks_mutex); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | EXPORT_SYMBOL(clk_unregister); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct { | 
					
						
							|  |  |  | 	unsigned long prate; | 
					
						
							|  |  |  | 	unsigned long rate; | 
					
						
							|  |  |  | } pllrate_table[] = { | 
					
						
							|  |  |  | 	{.prate = 0x00002001, .rate = 250000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00104801, .rate = 250000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00104C01, .rate = 262500000}, | 
					
						
							|  |  |  | 	{.prate = 0x00002401, .rate = 275000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00105001, .rate = 275000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00105401, .rate = 287500000}, | 
					
						
							|  |  |  | 	{.prate = 0x00002801, .rate = 300000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00105801, .rate = 300000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00105C01, .rate = 312500000}, | 
					
						
							|  |  |  | 	{.prate = 0x00002C01, .rate = 325000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00106001, .rate = 325000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00106401, .rate = 337500000}, | 
					
						
							|  |  |  | 	{.prate = 0x00003001, .rate = 350000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00106801, .rate = 350000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00106C01, .rate = 362500000}, | 
					
						
							|  |  |  | 	{.prate = 0x00003401, .rate = 375000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00107001, .rate = 375000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00107401, .rate = 387500000}, | 
					
						
							|  |  |  | 	{.prate = 0x00003801, .rate = 400000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00107801, .rate = 400000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00107C01, .rate = 412500000}, | 
					
						
							|  |  |  | 	{.prate = 0x00003C01, .rate = 425000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00108001, .rate = 425000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00108401, .rate = 437500000}, | 
					
						
							|  |  |  | 	{.prate = 0x00004001, .rate = 450000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00108801, .rate = 450000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00108C01, .rate = 462500000}, | 
					
						
							|  |  |  | 	{.prate = 0x00004401, .rate = 475000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00109001, .rate = 475000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00109401, .rate = 487500000}, | 
					
						
							|  |  |  | 	{.prate = 0x00004801, .rate = 500000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00109801, .rate = 500000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00104C00, .rate = 525000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00002400, .rate = 550000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00105000, .rate = 550000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00105400, .rate = 575000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00002800, .rate = 600000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00105800, .rate = 600000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00105C00, .rate = 625000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00002C00, .rate = 650000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00106000, .rate = 650000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00106400, .rate = 675000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00003000, .rate = 700000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00106800, .rate = 700000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00106C00, .rate = 725000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00003400, .rate = 750000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00107000, .rate = 750000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00107400, .rate = 775000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00003800, .rate = 800000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00107800, .rate = 800000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00107C00, .rate = 825000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00003C00, .rate = 850000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00108000, .rate = 850000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00108400, .rate = 875000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00004000, .rate = 900000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00108800, .rate = 900000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00108C00, .rate = 925000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00004400, .rate = 950000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00109000, .rate = 950000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00109400, .rate = 975000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00004800, .rate = 1000000000}, | 
					
						
							|  |  |  | 	{.prate = 0x00109800, .rate = 1000000000}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct { | 
					
						
							|  |  |  | 	unsigned long prate; | 
					
						
							|  |  |  | 	unsigned long drate; | 
					
						
							|  |  |  | } pddr_table[] = { | 
					
						
							|  |  |  | 	{.prate = 0x00100800, .drate = 44236800}, | 
					
						
							|  |  |  | 	{.prate = 0x00100C00, .drate = 66355200}, | 
					
						
							|  |  |  | 	{.prate = 0x00101000, .drate = 88473600}, | 
					
						
							|  |  |  | 	{.prate = 0x00101400, .drate = 110592000}, | 
					
						
							|  |  |  | 	{.prate = 0x00101800, .drate = 132710400}, | 
					
						
							|  |  |  | 	{.prate = 0x00101C01, .drate = 154828800}, | 
					
						
							|  |  |  | 	{.prate = 0x00102001, .drate = 176947200}, | 
					
						
							|  |  |  | 	{.prate = 0x00102401, .drate = 199065600}, | 
					
						
							|  |  |  | 	{.prate = 0x00102801, .drate = 221184000}, | 
					
						
							|  |  |  | 	{.prate = 0x00102C01, .drate = 243302400}, | 
					
						
							|  |  |  | 	{.prate = 0x00103001, .drate = 265420800}, | 
					
						
							|  |  |  | 	{.prate = 0x00103401, .drate = 287539200}, | 
					
						
							|  |  |  | 	{.prate = 0x00103801, .drate = 309657600}, | 
					
						
							|  |  |  | 	{.prate = 0x00103C01, .drate = 331776000}, | 
					
						
							|  |  |  | 	{.prate = 0x00104001, .drate = 353894400}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int __init clk_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef CONFIG_PUV3_PM
 | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 	u32 pllrate, divstatus = readl(PM_DIVSTATUS); | 
					
						
							|  |  |  | 	u32 pcgr_val = readl(PM_PCGR); | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pcgr_val |= PM_PCGR_BCLKMME | PM_PCGR_BCLKH264E | PM_PCGR_BCLKH264D | 
					
						
							|  |  |  | 			| PM_PCGR_HECLK | PM_PCGR_HDCLK; | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 	writel(pcgr_val, PM_PCGR); | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 	pllrate = readl(PM_PLLSYSSTATUS); | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* lookup pmclk_table */ | 
					
						
							|  |  |  | 	clk_mclk_clk.rate = 0; | 
					
						
							|  |  |  | 	for (i = 0; i < ARRAY_SIZE(pllrate_table); i++) { | 
					
						
							|  |  |  | 		if (pllrate == pllrate_table[i].prate) { | 
					
						
							|  |  |  | 			clk_mclk_clk.rate = pllrate_table[i].rate; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (clk_mclk_clk.rate) | 
					
						
							|  |  |  | 		clk_bclk32_clk.rate = clk_mclk_clk.rate / | 
					
						
							|  |  |  | 			(((divstatus & 0x0000f000) >> 12) + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 	pllrate = readl(PM_PLLDDRSTATUS); | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* lookup pddr_table */ | 
					
						
							|  |  |  | 	clk_ddr_clk.rate = 0; | 
					
						
							|  |  |  | 	for (i = 0; i < ARRAY_SIZE(pddr_table); i++) { | 
					
						
							|  |  |  | 		if (pllrate == pddr_table[i].prate) { | 
					
						
							|  |  |  | 			clk_ddr_clk.rate = pddr_table[i].drate; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-26 21:21:18 +08:00
										 |  |  | 	pllrate = readl(PM_PLLVGASTATUS); | 
					
						
							| 
									
										
										
										
											2011-02-26 20:23:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* lookup pvga_table */ | 
					
						
							|  |  |  | 	clk_vga_clk.rate = 0; | 
					
						
							|  |  |  | 	for (i = 0; i < ARRAY_SIZE(pllrate_table); i++) { | 
					
						
							|  |  |  | 		if (pllrate == pllrate_table[i].prate) { | 
					
						
							|  |  |  | 			clk_vga_clk.rate = pllrate_table[i].rate; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (clk_vga_clk.rate) | 
					
						
							|  |  |  | 		clk_vga_clk.rate = clk_vga_clk.rate / | 
					
						
							|  |  |  | 			(((divstatus & 0x00f00000) >> 20) + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	clk_register(&clk_vga_clk); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef CONFIG_ARCH_FPGA
 | 
					
						
							|  |  |  | 	clk_ddr_clk.rate = 33000000; | 
					
						
							|  |  |  | 	clk_mclk_clk.rate = 33000000; | 
					
						
							|  |  |  | 	clk_bclk32_clk.rate = 33000000; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	clk_register(&clk_ddr_clk); | 
					
						
							|  |  |  | 	clk_register(&clk_mclk_clk); | 
					
						
							|  |  |  | 	clk_register(&clk_bclk32_clk); | 
					
						
							|  |  |  | 	clk_register(&clk_ost_clk); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | core_initcall(clk_init); |