| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 1 | /* | 
|  | 2 | *  Copyright (C) 2009 ST-Ericsson | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 3 | *  Copyright (C) 2009 STMicroelectronics | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 4 | * | 
|  | 5 | * This program is free software; you can redistribute it and/or modify | 
|  | 6 | * it under the terms of the GNU General Public License version 2 as | 
|  | 7 | * published by the Free Software Foundation. | 
|  | 8 | */ | 
|  | 9 | #include <linux/module.h> | 
|  | 10 | #include <linux/kernel.h> | 
|  | 11 | #include <linux/list.h> | 
|  | 12 | #include <linux/errno.h> | 
|  | 13 | #include <linux/err.h> | 
|  | 14 | #include <linux/clk.h> | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 15 | #include <linux/io.h> | 
| Jean-Christop PLAGNIOL-VILLARD | 6d803ba | 2010-11-17 10:04:33 +0100 | [diff] [blame] | 16 | #include <linux/clkdev.h> | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 17 |  | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 18 | #include <plat/mtu.h> | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 19 | #include <mach/hardware.h> | 
|  | 20 | #include "clock.h" | 
|  | 21 |  | 
| Vincent Guittot | 763eef8 | 2010-12-03 18:18:39 +0100 | [diff] [blame] | 22 | #ifdef CONFIG_DEBUG_FS | 
|  | 23 | #include <linux/debugfs.h> | 
|  | 24 | #include <linux/uaccess.h>	/* for copy_from_user */ | 
|  | 25 | static LIST_HEAD(clk_list); | 
|  | 26 | #endif | 
|  | 27 |  | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 28 | #define PRCC_PCKEN		0x00 | 
|  | 29 | #define PRCC_PCKDIS		0x04 | 
|  | 30 | #define PRCC_KCKEN		0x08 | 
|  | 31 | #define PRCC_KCKDIS		0x0C | 
|  | 32 |  | 
|  | 33 | #define PRCM_YYCLKEN0_MGT_SET	0x510 | 
|  | 34 | #define PRCM_YYCLKEN1_MGT_SET	0x514 | 
|  | 35 | #define PRCM_YYCLKEN0_MGT_CLR	0x518 | 
|  | 36 | #define PRCM_YYCLKEN1_MGT_CLR	0x51C | 
|  | 37 | #define PRCM_YYCLKEN0_MGT_VAL	0x520 | 
|  | 38 | #define PRCM_YYCLKEN1_MGT_VAL	0x524 | 
|  | 39 |  | 
|  | 40 | #define PRCM_SVAMMDSPCLK_MGT	0x008 | 
|  | 41 | #define PRCM_SIAMMDSPCLK_MGT	0x00C | 
|  | 42 | #define PRCM_SGACLK_MGT		0x014 | 
|  | 43 | #define PRCM_UARTCLK_MGT	0x018 | 
|  | 44 | #define PRCM_MSP02CLK_MGT	0x01C | 
|  | 45 | #define PRCM_MSP1CLK_MGT	0x288 | 
|  | 46 | #define PRCM_I2CCLK_MGT		0x020 | 
|  | 47 | #define PRCM_SDMMCCLK_MGT	0x024 | 
|  | 48 | #define PRCM_SLIMCLK_MGT	0x028 | 
|  | 49 | #define PRCM_PER1CLK_MGT	0x02C | 
|  | 50 | #define PRCM_PER2CLK_MGT	0x030 | 
|  | 51 | #define PRCM_PER3CLK_MGT	0x034 | 
|  | 52 | #define PRCM_PER5CLK_MGT	0x038 | 
|  | 53 | #define PRCM_PER6CLK_MGT	0x03C | 
|  | 54 | #define PRCM_PER7CLK_MGT	0x040 | 
|  | 55 | #define PRCM_LCDCLK_MGT		0x044 | 
|  | 56 | #define PRCM_BMLCLK_MGT		0x04C | 
|  | 57 | #define PRCM_HSITXCLK_MGT	0x050 | 
|  | 58 | #define PRCM_HSIRXCLK_MGT	0x054 | 
|  | 59 | #define PRCM_HDMICLK_MGT	0x058 | 
|  | 60 | #define PRCM_APEATCLK_MGT	0x05C | 
|  | 61 | #define PRCM_APETRACECLK_MGT	0x060 | 
|  | 62 | #define PRCM_MCDECLK_MGT	0x064 | 
|  | 63 | #define PRCM_IPI2CCLK_MGT	0x068 | 
|  | 64 | #define PRCM_DSIALTCLK_MGT	0x06C | 
|  | 65 | #define PRCM_DMACLK_MGT		0x074 | 
|  | 66 | #define PRCM_B2R2CLK_MGT	0x078 | 
|  | 67 | #define PRCM_TVCLK_MGT		0x07C | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 68 | #define PRCM_TCR		0x1C8 | 
|  | 69 | #define PRCM_TCR_STOPPED	(1 << 16) | 
|  | 70 | #define PRCM_TCR_DOZE_MODE	(1 << 17) | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 71 | #define PRCM_UNIPROCLK_MGT	0x278 | 
|  | 72 | #define PRCM_SSPCLK_MGT		0x280 | 
|  | 73 | #define PRCM_RNGCLK_MGT		0x284 | 
|  | 74 | #define PRCM_UICCCLK_MGT	0x27C | 
|  | 75 |  | 
|  | 76 | #define PRCM_MGT_ENABLE		(1 << 8) | 
|  | 77 |  | 
|  | 78 | static DEFINE_SPINLOCK(clocks_lock); | 
|  | 79 |  | 
|  | 80 | static void __clk_enable(struct clk *clk) | 
|  | 81 | { | 
|  | 82 | if (clk->enabled++ == 0) { | 
|  | 83 | if (clk->parent_cluster) | 
|  | 84 | __clk_enable(clk->parent_cluster); | 
|  | 85 |  | 
|  | 86 | if (clk->parent_periph) | 
|  | 87 | __clk_enable(clk->parent_periph); | 
|  | 88 |  | 
|  | 89 | if (clk->ops && clk->ops->enable) | 
|  | 90 | clk->ops->enable(clk); | 
|  | 91 | } | 
|  | 92 | } | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 93 |  | 
|  | 94 | int clk_enable(struct clk *clk) | 
|  | 95 | { | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 96 | unsigned long flags; | 
|  | 97 |  | 
|  | 98 | spin_lock_irqsave(&clocks_lock, flags); | 
|  | 99 | __clk_enable(clk); | 
|  | 100 | spin_unlock_irqrestore(&clocks_lock, flags); | 
|  | 101 |  | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 102 | return 0; | 
|  | 103 | } | 
|  | 104 | EXPORT_SYMBOL(clk_enable); | 
|  | 105 |  | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 106 | static void __clk_disable(struct clk *clk) | 
|  | 107 | { | 
|  | 108 | if (--clk->enabled == 0) { | 
|  | 109 | if (clk->ops && clk->ops->disable) | 
|  | 110 | clk->ops->disable(clk); | 
|  | 111 |  | 
|  | 112 | if (clk->parent_periph) | 
|  | 113 | __clk_disable(clk->parent_periph); | 
|  | 114 |  | 
|  | 115 | if (clk->parent_cluster) | 
|  | 116 | __clk_disable(clk->parent_cluster); | 
|  | 117 | } | 
|  | 118 | } | 
|  | 119 |  | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 120 | void clk_disable(struct clk *clk) | 
|  | 121 | { | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 122 | unsigned long flags; | 
|  | 123 |  | 
|  | 124 | WARN_ON(!clk->enabled); | 
|  | 125 |  | 
|  | 126 | spin_lock_irqsave(&clocks_lock, flags); | 
|  | 127 | __clk_disable(clk); | 
|  | 128 | spin_unlock_irqrestore(&clocks_lock, flags); | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 129 | } | 
|  | 130 | EXPORT_SYMBOL(clk_disable); | 
|  | 131 |  | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 132 | /* | 
|  | 133 | * The MTU has a separate, rather complex muxing setup | 
|  | 134 | * with alternative parents (peripheral cluster or | 
|  | 135 | * ULP or fixed 32768 Hz) depending on settings | 
|  | 136 | */ | 
|  | 137 | static unsigned long clk_mtu_get_rate(struct clk *clk) | 
|  | 138 | { | 
| Rabin Vincent | 92389ca | 2010-12-08 11:07:57 +0530 | [diff] [blame] | 139 | void __iomem *addr; | 
| Sundar Iyer | f306954 | 2010-12-03 20:35:51 +0530 | [diff] [blame] | 140 | u32 tcr; | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 141 | int mtu = (int) clk->data; | 
|  | 142 | /* | 
|  | 143 | * One of these is selected eventually | 
|  | 144 | * TODO: Replace the constant with a reference | 
|  | 145 | * to the ULP source once this is modeled. | 
|  | 146 | */ | 
|  | 147 | unsigned long clk32k = 32768; | 
|  | 148 | unsigned long mturate; | 
|  | 149 | unsigned long retclk; | 
|  | 150 |  | 
| Rabin Vincent | 92389ca | 2010-12-08 11:07:57 +0530 | [diff] [blame] | 151 | if (cpu_is_u5500()) | 
|  | 152 | addr = __io_address(U5500_PRCMU_BASE); | 
|  | 153 | else if (cpu_is_u8500()) | 
|  | 154 | addr = __io_address(U8500_PRCMU_BASE); | 
|  | 155 | else | 
|  | 156 | ux500_unknown_soc(); | 
|  | 157 |  | 
| Sundar Iyer | f306954 | 2010-12-03 20:35:51 +0530 | [diff] [blame] | 158 | /* | 
|  | 159 | * On a startup, always conifgure the TCR to the doze mode; | 
|  | 160 | * bootloaders do it for us. Do this in the kernel too. | 
|  | 161 | */ | 
| Rabin Vincent | 92389ca | 2010-12-08 11:07:57 +0530 | [diff] [blame] | 162 | writel(PRCM_TCR_DOZE_MODE, addr + PRCM_TCR); | 
| Sundar Iyer | f306954 | 2010-12-03 20:35:51 +0530 | [diff] [blame] | 163 |  | 
| Rabin Vincent | 92389ca | 2010-12-08 11:07:57 +0530 | [diff] [blame] | 164 | tcr = readl(addr + PRCM_TCR); | 
| Sundar Iyer | f306954 | 2010-12-03 20:35:51 +0530 | [diff] [blame] | 165 |  | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 166 | /* Get the rate from the parent as a default */ | 
|  | 167 | if (clk->parent_periph) | 
|  | 168 | mturate = clk_get_rate(clk->parent_periph); | 
|  | 169 | else if (clk->parent_cluster) | 
|  | 170 | mturate = clk_get_rate(clk->parent_cluster); | 
|  | 171 | else | 
|  | 172 | /* We need to be connected SOMEWHERE */ | 
|  | 173 | BUG(); | 
|  | 174 |  | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 175 | /* Return the clock selected for this MTU */ | 
|  | 176 | if (tcr & (1 << mtu)) | 
|  | 177 | retclk = clk32k; | 
|  | 178 | else | 
|  | 179 | retclk = mturate; | 
|  | 180 |  | 
|  | 181 | pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk); | 
|  | 182 | return retclk; | 
|  | 183 | } | 
|  | 184 |  | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 185 | unsigned long clk_get_rate(struct clk *clk) | 
|  | 186 | { | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 187 | unsigned long rate; | 
|  | 188 |  | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 189 | /* | 
|  | 190 | * If there is a custom getrate callback for this clock, | 
|  | 191 | * it will take precedence. | 
|  | 192 | */ | 
|  | 193 | if (clk->get_rate) | 
|  | 194 | return clk->get_rate(clk); | 
|  | 195 |  | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 196 | if (clk->ops && clk->ops->get_rate) | 
|  | 197 | return clk->ops->get_rate(clk); | 
|  | 198 |  | 
|  | 199 | rate = clk->rate; | 
|  | 200 | if (!rate) { | 
|  | 201 | if (clk->parent_periph) | 
|  | 202 | rate = clk_get_rate(clk->parent_periph); | 
|  | 203 | else if (clk->parent_cluster) | 
|  | 204 | rate = clk_get_rate(clk->parent_cluster); | 
|  | 205 | } | 
|  | 206 |  | 
|  | 207 | return rate; | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 208 | } | 
|  | 209 | EXPORT_SYMBOL(clk_get_rate); | 
|  | 210 |  | 
|  | 211 | long clk_round_rate(struct clk *clk, unsigned long rate) | 
|  | 212 | { | 
|  | 213 | /*TODO*/ | 
|  | 214 | return rate; | 
|  | 215 | } | 
|  | 216 | EXPORT_SYMBOL(clk_round_rate); | 
|  | 217 |  | 
|  | 218 | int clk_set_rate(struct clk *clk, unsigned long rate) | 
|  | 219 | { | 
|  | 220 | clk->rate = rate; | 
|  | 221 | return 0; | 
|  | 222 | } | 
|  | 223 | EXPORT_SYMBOL(clk_set_rate); | 
|  | 224 |  | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 225 | static void clk_prcmu_enable(struct clk *clk) | 
|  | 226 | { | 
|  | 227 | void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE) | 
|  | 228 | + PRCM_YYCLKEN0_MGT_SET + clk->prcmu_cg_off; | 
|  | 229 |  | 
|  | 230 | writel(1 << clk->prcmu_cg_bit, cg_set_reg); | 
|  | 231 | } | 
|  | 232 |  | 
|  | 233 | static void clk_prcmu_disable(struct clk *clk) | 
|  | 234 | { | 
|  | 235 | void __iomem *cg_clr_reg = __io_address(U8500_PRCMU_BASE) | 
|  | 236 | + PRCM_YYCLKEN0_MGT_CLR + clk->prcmu_cg_off; | 
|  | 237 |  | 
|  | 238 | writel(1 << clk->prcmu_cg_bit, cg_clr_reg); | 
|  | 239 | } | 
|  | 240 |  | 
|  | 241 | /* ED doesn't have the combined set/clr registers */ | 
|  | 242 | static void clk_prcmu_ed_enable(struct clk *clk) | 
|  | 243 | { | 
|  | 244 | void __iomem *addr = __io_address(U8500_PRCMU_BASE) | 
|  | 245 | + clk->prcmu_cg_mgt; | 
|  | 246 |  | 
|  | 247 | writel(readl(addr) | PRCM_MGT_ENABLE, addr); | 
|  | 248 | } | 
|  | 249 |  | 
|  | 250 | static void clk_prcmu_ed_disable(struct clk *clk) | 
|  | 251 | { | 
|  | 252 | void __iomem *addr = __io_address(U8500_PRCMU_BASE) | 
|  | 253 | + clk->prcmu_cg_mgt; | 
|  | 254 |  | 
|  | 255 | writel(readl(addr) & ~PRCM_MGT_ENABLE, addr); | 
|  | 256 | } | 
|  | 257 |  | 
|  | 258 | static struct clkops clk_prcmu_ops = { | 
|  | 259 | .enable = clk_prcmu_enable, | 
|  | 260 | .disable = clk_prcmu_disable, | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 261 | }; | 
|  | 262 |  | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 263 | static unsigned int clkrst_base[] = { | 
|  | 264 | [1] = U8500_CLKRST1_BASE, | 
|  | 265 | [2] = U8500_CLKRST2_BASE, | 
|  | 266 | [3] = U8500_CLKRST3_BASE, | 
|  | 267 | [5] = U8500_CLKRST5_BASE, | 
|  | 268 | [6] = U8500_CLKRST6_BASE, | 
|  | 269 | [7] = U8500_CLKRST7_BASE_ED, | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 270 | }; | 
|  | 271 |  | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 272 | static void clk_prcc_enable(struct clk *clk) | 
|  | 273 | { | 
|  | 274 | void __iomem *addr = __io_address(clkrst_base[clk->cluster]); | 
|  | 275 |  | 
|  | 276 | if (clk->prcc_kernel != -1) | 
|  | 277 | writel(1 << clk->prcc_kernel, addr + PRCC_KCKEN); | 
|  | 278 |  | 
|  | 279 | if (clk->prcc_bus != -1) | 
|  | 280 | writel(1 << clk->prcc_bus, addr + PRCC_PCKEN); | 
|  | 281 | } | 
|  | 282 |  | 
|  | 283 | static void clk_prcc_disable(struct clk *clk) | 
|  | 284 | { | 
|  | 285 | void __iomem *addr = __io_address(clkrst_base[clk->cluster]); | 
|  | 286 |  | 
|  | 287 | if (clk->prcc_bus != -1) | 
|  | 288 | writel(1 << clk->prcc_bus, addr + PRCC_PCKDIS); | 
|  | 289 |  | 
|  | 290 | if (clk->prcc_kernel != -1) | 
|  | 291 | writel(1 << clk->prcc_kernel, addr + PRCC_KCKDIS); | 
|  | 292 | } | 
|  | 293 |  | 
|  | 294 | static struct clkops clk_prcc_ops = { | 
|  | 295 | .enable = clk_prcc_enable, | 
|  | 296 | .disable = clk_prcc_disable, | 
|  | 297 | }; | 
|  | 298 |  | 
|  | 299 | static struct clk clk_32khz = { | 
| Vincent Guittot | 763eef8 | 2010-12-03 18:18:39 +0100 | [diff] [blame] | 300 | .name =  "clk_32khz", | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 301 | .rate = 32000, | 
|  | 302 | }; | 
|  | 303 |  | 
|  | 304 | /* | 
|  | 305 | * PRCMU level clock gating | 
|  | 306 | */ | 
|  | 307 |  | 
|  | 308 | /* Bank 0 */ | 
|  | 309 | static DEFINE_PRCMU_CLK(svaclk,		0x0, 2, SVAMMDSPCLK); | 
|  | 310 | static DEFINE_PRCMU_CLK(siaclk,		0x0, 3, SIAMMDSPCLK); | 
|  | 311 | static DEFINE_PRCMU_CLK(sgaclk,		0x0, 4, SGACLK); | 
|  | 312 | static DEFINE_PRCMU_CLK_RATE(uartclk,	0x0, 5, UARTCLK, 38400000); | 
|  | 313 | static DEFINE_PRCMU_CLK(msp02clk,	0x0, 6, MSP02CLK); | 
|  | 314 | static DEFINE_PRCMU_CLK(msp1clk,	0x0, 7, MSP1CLK); /* v1 */ | 
|  | 315 | static DEFINE_PRCMU_CLK_RATE(i2cclk,	0x0, 8, I2CCLK, 48000000); | 
|  | 316 | static DEFINE_PRCMU_CLK_RATE(sdmmcclk,	0x0, 9, SDMMCCLK, 50000000); | 
|  | 317 | static DEFINE_PRCMU_CLK(slimclk,	0x0, 10, SLIMCLK); | 
|  | 318 | static DEFINE_PRCMU_CLK(per1clk,	0x0, 11, PER1CLK); | 
|  | 319 | static DEFINE_PRCMU_CLK(per2clk,	0x0, 12, PER2CLK); | 
|  | 320 | static DEFINE_PRCMU_CLK(per3clk,	0x0, 13, PER3CLK); | 
|  | 321 | static DEFINE_PRCMU_CLK(per5clk,	0x0, 14, PER5CLK); | 
|  | 322 | static DEFINE_PRCMU_CLK_RATE(per6clk,	0x0, 15, PER6CLK, 133330000); | 
|  | 323 | static DEFINE_PRCMU_CLK_RATE(per7clk,	0x0, 16, PER7CLK, 100000000); | 
|  | 324 | static DEFINE_PRCMU_CLK(lcdclk,		0x0, 17, LCDCLK); | 
|  | 325 | static DEFINE_PRCMU_CLK(bmlclk,		0x0, 18, BMLCLK); | 
|  | 326 | static DEFINE_PRCMU_CLK(hsitxclk,	0x0, 19, HSITXCLK); | 
|  | 327 | static DEFINE_PRCMU_CLK(hsirxclk,	0x0, 20, HSIRXCLK); | 
|  | 328 | static DEFINE_PRCMU_CLK(hdmiclk,	0x0, 21, HDMICLK); | 
|  | 329 | static DEFINE_PRCMU_CLK(apeatclk,	0x0, 22, APEATCLK); | 
|  | 330 | static DEFINE_PRCMU_CLK(apetraceclk,	0x0, 23, APETRACECLK); | 
|  | 331 | static DEFINE_PRCMU_CLK(mcdeclk,	0x0, 24, MCDECLK); | 
|  | 332 | static DEFINE_PRCMU_CLK(ipi2clk,	0x0, 25, IPI2CCLK); | 
|  | 333 | static DEFINE_PRCMU_CLK(dsialtclk,	0x0, 26, DSIALTCLK); /* v1 */ | 
|  | 334 | static DEFINE_PRCMU_CLK(dmaclk,		0x0, 27, DMACLK); | 
|  | 335 | static DEFINE_PRCMU_CLK(b2r2clk,	0x0, 28, B2R2CLK); | 
|  | 336 | static DEFINE_PRCMU_CLK(tvclk,		0x0, 29, TVCLK); | 
|  | 337 | static DEFINE_PRCMU_CLK(uniproclk,	0x0, 30, UNIPROCLK); /* v1 */ | 
|  | 338 | static DEFINE_PRCMU_CLK_RATE(sspclk,	0x0, 31, SSPCLK, 48000000); /* v1 */ | 
|  | 339 |  | 
|  | 340 | /* Bank 1 */ | 
|  | 341 | static DEFINE_PRCMU_CLK(rngclk,		0x4, 0, RNGCLK); /* v1 */ | 
|  | 342 | static DEFINE_PRCMU_CLK(uiccclk,	0x4, 1, UICCCLK); /* v1 */ | 
|  | 343 |  | 
|  | 344 | /* | 
|  | 345 | * PRCC level clock gating | 
|  | 346 | * Format: per#, clk, PCKEN bit, KCKEN bit, parent | 
|  | 347 | */ | 
|  | 348 |  | 
|  | 349 | /* Peripheral Cluster #1 */ | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 350 | static DEFINE_PRCC_CLK(1, i2c4,		10, 9, &clk_i2cclk); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 351 | static DEFINE_PRCC_CLK(1, gpio0,	9, -1, NULL); | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 352 | static DEFINE_PRCC_CLK(1, slimbus0,	8,  8, &clk_slimclk); | 
|  | 353 | static DEFINE_PRCC_CLK(1, spi3_ed,	7,  7, NULL); | 
|  | 354 | static DEFINE_PRCC_CLK(1, spi3_v1,	7, -1, NULL); | 
|  | 355 | static DEFINE_PRCC_CLK(1, i2c2,		6,  6, &clk_i2cclk); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 356 | static DEFINE_PRCC_CLK(1, sdi0,		5,  5, &clk_sdmmcclk); | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 357 | static DEFINE_PRCC_CLK(1, msp1_ed,	4,  4, &clk_msp02clk); | 
|  | 358 | static DEFINE_PRCC_CLK(1, msp1_v1,	4,  4, &clk_msp1clk); | 
|  | 359 | static DEFINE_PRCC_CLK(1, msp0,		3,  3, &clk_msp02clk); | 
|  | 360 | static DEFINE_PRCC_CLK(1, i2c1,		2,  2, &clk_i2cclk); | 
|  | 361 | static DEFINE_PRCC_CLK(1, uart1,	1,  1, &clk_uartclk); | 
|  | 362 | static DEFINE_PRCC_CLK(1, uart0,	0,  0, &clk_uartclk); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 363 |  | 
|  | 364 | /* Peripheral Cluster #2 */ | 
|  | 365 |  | 
|  | 366 | static DEFINE_PRCC_CLK(2, gpio1_ed,	12, -1, NULL); | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 367 | static DEFINE_PRCC_CLK(2, ssitx_ed,	11, -1, NULL); | 
|  | 368 | static DEFINE_PRCC_CLK(2, ssirx_ed,	10, -1, NULL); | 
|  | 369 | static DEFINE_PRCC_CLK(2, spi0_ed,	 9, -1, NULL); | 
|  | 370 | static DEFINE_PRCC_CLK(2, sdi3_ed,	 8,  6, &clk_sdmmcclk); | 
|  | 371 | static DEFINE_PRCC_CLK(2, sdi1_ed,	 7,  5, &clk_sdmmcclk); | 
|  | 372 | static DEFINE_PRCC_CLK(2, msp2_ed,	 6,  4, &clk_msp02clk); | 
|  | 373 | static DEFINE_PRCC_CLK(2, sdi4_ed,	 4,  2, &clk_sdmmcclk); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 374 | static DEFINE_PRCC_CLK(2, pwl_ed,	 3,  1, NULL); | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 375 | static DEFINE_PRCC_CLK(2, spi1_ed,	 2, -1, NULL); | 
|  | 376 | static DEFINE_PRCC_CLK(2, spi2_ed,	 1, -1, NULL); | 
|  | 377 | static DEFINE_PRCC_CLK(2, i2c3_ed,	 0,  0, &clk_i2cclk); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 378 |  | 
|  | 379 | static DEFINE_PRCC_CLK(2, gpio1_v1,	11, -1, NULL); | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 380 | static DEFINE_PRCC_CLK(2, ssitx_v1,	10,  7, NULL); | 
|  | 381 | static DEFINE_PRCC_CLK(2, ssirx_v1,	 9,  6, NULL); | 
|  | 382 | static DEFINE_PRCC_CLK(2, spi0_v1,	 8, -1, NULL); | 
|  | 383 | static DEFINE_PRCC_CLK(2, sdi3_v1,	 7,  5, &clk_sdmmcclk); | 
|  | 384 | static DEFINE_PRCC_CLK(2, sdi1_v1,	 6,  4, &clk_sdmmcclk); | 
|  | 385 | static DEFINE_PRCC_CLK(2, msp2_v1,	 5,  3, &clk_msp02clk); | 
|  | 386 | static DEFINE_PRCC_CLK(2, sdi4_v1,	 4,  2, &clk_sdmmcclk); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 387 | static DEFINE_PRCC_CLK(2, pwl_v1,	 3,  1, NULL); | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 388 | static DEFINE_PRCC_CLK(2, spi1_v1,	 2, -1, NULL); | 
|  | 389 | static DEFINE_PRCC_CLK(2, spi2_v1,	 1, -1, NULL); | 
|  | 390 | static DEFINE_PRCC_CLK(2, i2c3_v1,	 0,  0, &clk_i2cclk); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 391 |  | 
|  | 392 | /* Peripheral Cluster #3 */ | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 393 | static DEFINE_PRCC_CLK(3, gpio2,	8, -1, NULL); | 
|  | 394 | static DEFINE_PRCC_CLK(3, sdi5,		7,  7, &clk_sdmmcclk); | 
|  | 395 | static DEFINE_PRCC_CLK(3, uart2,	6,  6, &clk_uartclk); | 
|  | 396 | static DEFINE_PRCC_CLK(3, ske,		5,  5, &clk_32khz); | 
|  | 397 | static DEFINE_PRCC_CLK(3, sdi2,		4,  4, &clk_sdmmcclk); | 
|  | 398 | static DEFINE_PRCC_CLK(3, i2c0,		3,  3, &clk_i2cclk); | 
|  | 399 | static DEFINE_PRCC_CLK(3, ssp1_ed,	2,  2, &clk_i2cclk); | 
|  | 400 | static DEFINE_PRCC_CLK(3, ssp0_ed,	1,  1, &clk_i2cclk); | 
|  | 401 | static DEFINE_PRCC_CLK(3, ssp1_v1,	2,  2, &clk_sspclk); | 
|  | 402 | static DEFINE_PRCC_CLK(3, ssp0_v1,	1,  1, &clk_sspclk); | 
|  | 403 | static DEFINE_PRCC_CLK(3, fsmc,		0, -1, NULL); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 404 |  | 
|  | 405 | /* Peripheral Cluster #4 is in the always on domain */ | 
|  | 406 |  | 
|  | 407 | /* Peripheral Cluster #5 */ | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 408 | static DEFINE_PRCC_CLK(5, gpio3,	1, -1, NULL); | 
|  | 409 | static DEFINE_PRCC_CLK(5, usb_ed,	0,  0, &clk_i2cclk); | 
|  | 410 | static DEFINE_PRCC_CLK(5, usb_v1,	0,  0, NULL); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 411 |  | 
|  | 412 | /* Peripheral Cluster #6 */ | 
|  | 413 |  | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 414 | /* MTU ID in data */ | 
|  | 415 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); | 
|  | 416 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 417 | static DEFINE_PRCC_CLK(6, cfgreg_v1,	6,  6, NULL); | 
|  | 418 | static DEFINE_PRCC_CLK(6, dmc_ed,	6,  6, NULL); | 
|  | 419 | static DEFINE_PRCC_CLK(6, hash1,	5, -1, NULL); | 
|  | 420 | static DEFINE_PRCC_CLK(6, unipro_v1,	4,  1, &clk_uniproclk); | 
|  | 421 | static DEFINE_PRCC_CLK(6, cryp1_ed,	4, -1, NULL); | 
|  | 422 | static DEFINE_PRCC_CLK(6, pka,		3, -1, NULL); | 
|  | 423 | static DEFINE_PRCC_CLK(6, hash0,	2, -1, NULL); | 
|  | 424 | static DEFINE_PRCC_CLK(6, cryp0,	1, -1, NULL); | 
|  | 425 | static DEFINE_PRCC_CLK(6, rng_ed,	0,  0, &clk_i2cclk); | 
|  | 426 | static DEFINE_PRCC_CLK(6, rng_v1,	0,  0, &clk_rngclk); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 427 |  | 
|  | 428 | /* Peripheral Cluster #7 */ | 
|  | 429 |  | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 430 | static DEFINE_PRCC_CLK(7, tzpc0_ed,	4, -1, NULL); | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 431 | /* MTU ID in data */ | 
|  | 432 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1); | 
|  | 433 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0); | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 434 | static DEFINE_PRCC_CLK(7, wdg_ed,	1, -1, NULL); | 
|  | 435 | static DEFINE_PRCC_CLK(7, cfgreg_ed,	0, -1, NULL); | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 436 |  | 
| Vincent Guittot | 763eef8 | 2010-12-03 18:18:39 +0100 | [diff] [blame] | 437 | static struct clk clk_dummy_apb_pclk = { | 
|  | 438 | .name = "apb_pclk", | 
|  | 439 | }; | 
| Russell King | 3126c7b | 2010-07-15 11:01:17 +0100 | [diff] [blame] | 440 |  | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 441 | static struct clk_lookup u8500_common_clks[] = { | 
| Russell King | 3126c7b | 2010-07-15 11:01:17 +0100 | [diff] [blame] | 442 | CLK(dummy_apb_pclk, NULL,	"apb_pclk"), | 
|  | 443 |  | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 444 | /* Peripheral Cluster #1 */ | 
| Rabin Vincent | af7dc22 | 2010-05-06 11:14:17 +0100 | [diff] [blame] | 445 | CLK(gpio0,	"gpio.0",	NULL), | 
|  | 446 | CLK(gpio0,	"gpio.1",	NULL), | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 447 | CLK(slimbus0,	"slimbus0",	NULL), | 
|  | 448 | CLK(i2c2,	"nmk-i2c.2",	NULL), | 
|  | 449 | CLK(sdi0,	"sdi0",		NULL), | 
|  | 450 | CLK(msp0,	"msp0",		NULL), | 
|  | 451 | CLK(i2c1,	"nmk-i2c.1",	NULL), | 
|  | 452 | CLK(uart1,	"uart1",	NULL), | 
|  | 453 | CLK(uart0,	"uart0",	NULL), | 
|  | 454 |  | 
|  | 455 | /* Peripheral Cluster #3 */ | 
| Rabin Vincent | af7dc22 | 2010-05-06 11:14:17 +0100 | [diff] [blame] | 456 | CLK(gpio2,	"gpio.2",	NULL), | 
|  | 457 | CLK(gpio2,	"gpio.3",	NULL), | 
|  | 458 | CLK(gpio2,	"gpio.4",	NULL), | 
|  | 459 | CLK(gpio2,	"gpio.5",	NULL), | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 460 | CLK(sdi5,	"sdi5",		NULL), | 
|  | 461 | CLK(uart2,	"uart2",	NULL), | 
|  | 462 | CLK(ske,	"ske",		NULL), | 
| Sundar Iyer | 4c61c84 | 2010-09-29 19:43:09 -0700 | [diff] [blame] | 463 | CLK(ske,	"nmk-ske-keypad",	NULL), | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 464 | CLK(sdi2,	"sdi2",		NULL), | 
|  | 465 | CLK(i2c0,	"nmk-i2c.0",	NULL), | 
|  | 466 | CLK(fsmc,	"fsmc",		NULL), | 
|  | 467 |  | 
|  | 468 | /* Peripheral Cluster #5 */ | 
| Rabin Vincent | af7dc22 | 2010-05-06 11:14:17 +0100 | [diff] [blame] | 469 | CLK(gpio3,	"gpio.8",	NULL), | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 470 |  | 
|  | 471 | /* Peripheral Cluster #6 */ | 
|  | 472 | CLK(hash1,	"hash1",	NULL), | 
|  | 473 | CLK(pka,	"pka",		NULL), | 
|  | 474 | CLK(hash0,	"hash0",	NULL), | 
|  | 475 | CLK(cryp0,	"cryp0",	NULL), | 
|  | 476 |  | 
|  | 477 | /* PRCMU level clock gating */ | 
|  | 478 |  | 
|  | 479 | /* Bank 0 */ | 
|  | 480 | CLK(svaclk,	"sva",		NULL), | 
|  | 481 | CLK(siaclk,	"sia",		NULL), | 
|  | 482 | CLK(sgaclk,	"sga",		NULL), | 
|  | 483 | CLK(slimclk,	"slim",		NULL), | 
|  | 484 | CLK(lcdclk,	"lcd",		NULL), | 
|  | 485 | CLK(bmlclk,	"bml",		NULL), | 
|  | 486 | CLK(hsitxclk,	"stm-hsi.0",	NULL), | 
|  | 487 | CLK(hsirxclk,	"stm-hsi.1",	NULL), | 
|  | 488 | CLK(hdmiclk,	"hdmi",		NULL), | 
|  | 489 | CLK(apeatclk,	"apeat",	NULL), | 
|  | 490 | CLK(apetraceclk,	"apetrace",	NULL), | 
|  | 491 | CLK(mcdeclk,	"mcde",		NULL), | 
|  | 492 | CLK(ipi2clk,	"ipi2",		NULL), | 
| Linus Walleij | 7b8ddb0 | 2010-05-27 15:21:26 -0700 | [diff] [blame] | 493 | CLK(dmaclk,	"dma40.0",	NULL), | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 494 | CLK(b2r2clk,	"b2r2",		NULL), | 
|  | 495 | CLK(tvclk,	"tv",		NULL), | 
|  | 496 | }; | 
|  | 497 |  | 
|  | 498 | static struct clk_lookup u8500_ed_clks[] = { | 
|  | 499 | /* Peripheral Cluster #1 */ | 
|  | 500 | CLK(spi3_ed,	"spi3",		NULL), | 
|  | 501 | CLK(msp1_ed,	"msp1",		NULL), | 
|  | 502 |  | 
|  | 503 | /* Peripheral Cluster #2 */ | 
| Rabin Vincent | af7dc22 | 2010-05-06 11:14:17 +0100 | [diff] [blame] | 504 | CLK(gpio1_ed,	"gpio.6",	NULL), | 
|  | 505 | CLK(gpio1_ed,	"gpio.7",	NULL), | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 506 | CLK(ssitx_ed,	"ssitx",	NULL), | 
|  | 507 | CLK(ssirx_ed,	"ssirx",	NULL), | 
|  | 508 | CLK(spi0_ed,	"spi0",		NULL), | 
|  | 509 | CLK(sdi3_ed,	"sdi3",		NULL), | 
|  | 510 | CLK(sdi1_ed,	"sdi1",		NULL), | 
|  | 511 | CLK(msp2_ed,	"msp2",		NULL), | 
|  | 512 | CLK(sdi4_ed,	"sdi4",		NULL), | 
|  | 513 | CLK(pwl_ed,	"pwl",		NULL), | 
|  | 514 | CLK(spi1_ed,	"spi1",		NULL), | 
|  | 515 | CLK(spi2_ed,	"spi2",		NULL), | 
|  | 516 | CLK(i2c3_ed,	"nmk-i2c.3",	NULL), | 
|  | 517 |  | 
|  | 518 | /* Peripheral Cluster #3 */ | 
|  | 519 | CLK(ssp1_ed,	"ssp1",		NULL), | 
|  | 520 | CLK(ssp0_ed,	"ssp0",		NULL), | 
|  | 521 |  | 
|  | 522 | /* Peripheral Cluster #5 */ | 
|  | 523 | CLK(usb_ed,	"musb_hdrc.0",	"usb"), | 
|  | 524 |  | 
|  | 525 | /* Peripheral Cluster #6 */ | 
|  | 526 | CLK(dmc_ed,	"dmc",		NULL), | 
|  | 527 | CLK(cryp1_ed,	"cryp1",	NULL), | 
|  | 528 | CLK(rng_ed,	"rng",		NULL), | 
|  | 529 |  | 
|  | 530 | /* Peripheral Cluster #7 */ | 
|  | 531 | CLK(tzpc0_ed,	"tzpc0",	NULL), | 
|  | 532 | CLK(mtu1_ed,	"mtu1",		NULL), | 
|  | 533 | CLK(mtu0_ed,	"mtu0",		NULL), | 
|  | 534 | CLK(wdg_ed,	"wdg",		NULL), | 
|  | 535 | CLK(cfgreg_ed,	"cfgreg",	NULL), | 
|  | 536 | }; | 
|  | 537 |  | 
|  | 538 | static struct clk_lookup u8500_v1_clks[] = { | 
|  | 539 | /* Peripheral Cluster #1 */ | 
| Sundar Iyer | 592b2f2 | 2010-12-03 20:35:52 +0530 | [diff] [blame] | 540 | CLK(i2c4,	"nmk-i2c.4",	NULL), | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 541 | CLK(spi3_v1,	"spi3",		NULL), | 
|  | 542 | CLK(msp1_v1,	"msp1",		NULL), | 
|  | 543 |  | 
|  | 544 | /* Peripheral Cluster #2 */ | 
| Rabin Vincent | af7dc22 | 2010-05-06 11:14:17 +0100 | [diff] [blame] | 545 | CLK(gpio1_v1,	"gpio.6",	NULL), | 
|  | 546 | CLK(gpio1_v1,	"gpio.7",	NULL), | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 547 | CLK(ssitx_v1,	"ssitx",	NULL), | 
|  | 548 | CLK(ssirx_v1,	"ssirx",	NULL), | 
|  | 549 | CLK(spi0_v1,	"spi0",		NULL), | 
|  | 550 | CLK(sdi3_v1,	"sdi3",		NULL), | 
|  | 551 | CLK(sdi1_v1,	"sdi1",		NULL), | 
|  | 552 | CLK(msp2_v1,	"msp2",		NULL), | 
|  | 553 | CLK(sdi4_v1,	"sdi4",		NULL), | 
|  | 554 | CLK(pwl_v1,	"pwl",		NULL), | 
|  | 555 | CLK(spi1_v1,	"spi1",		NULL), | 
|  | 556 | CLK(spi2_v1,	"spi2",		NULL), | 
|  | 557 | CLK(i2c3_v1,	"nmk-i2c.3",	NULL), | 
|  | 558 |  | 
|  | 559 | /* Peripheral Cluster #3 */ | 
|  | 560 | CLK(ssp1_v1,	"ssp1",		NULL), | 
|  | 561 | CLK(ssp0_v1,	"ssp0",		NULL), | 
|  | 562 |  | 
|  | 563 | /* Peripheral Cluster #5 */ | 
|  | 564 | CLK(usb_v1,	"musb_hdrc.0",	"usb"), | 
|  | 565 |  | 
|  | 566 | /* Peripheral Cluster #6 */ | 
|  | 567 | CLK(mtu1_v1,	"mtu1",		NULL), | 
|  | 568 | CLK(mtu0_v1,	"mtu0",		NULL), | 
|  | 569 | CLK(cfgreg_v1,	"cfgreg",	NULL), | 
|  | 570 | CLK(hash1,	"hash1",	NULL), | 
|  | 571 | CLK(unipro_v1,	"unipro",	NULL), | 
|  | 572 | CLK(rng_v1,	"rng",		NULL), | 
|  | 573 |  | 
|  | 574 | /* PRCMU level clock gating */ | 
|  | 575 |  | 
|  | 576 | /* Bank 0 */ | 
|  | 577 | CLK(uniproclk,	"uniproclk",	NULL), | 
|  | 578 | CLK(dsialtclk,	"dsialt",	NULL), | 
|  | 579 |  | 
|  | 580 | /* Bank 1 */ | 
|  | 581 | CLK(rngclk,	"rng",		NULL), | 
|  | 582 | CLK(uiccclk,	"uicc",		NULL), | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 583 | }; | 
|  | 584 |  | 
| Vincent Guittot | 763eef8 | 2010-12-03 18:18:39 +0100 | [diff] [blame] | 585 | #ifdef CONFIG_DEBUG_FS | 
|  | 586 | /* | 
|  | 587 | *	debugfs support to trace clock tree hierarchy and attributes with | 
|  | 588 | *	powerdebug | 
|  | 589 | */ | 
|  | 590 | static struct dentry *clk_debugfs_root; | 
|  | 591 |  | 
|  | 592 | void __init clk_debugfs_add_table(struct clk_lookup *cl, size_t num) | 
|  | 593 | { | 
|  | 594 | while (num--) { | 
|  | 595 | /* Check that the clock has not been already registered */ | 
|  | 596 | if (!(cl->clk->list.prev != cl->clk->list.next)) | 
|  | 597 | list_add_tail(&cl->clk->list, &clk_list); | 
|  | 598 |  | 
|  | 599 | cl++; | 
|  | 600 | } | 
|  | 601 | } | 
|  | 602 |  | 
|  | 603 | static ssize_t usecount_dbg_read(struct file *file, char __user *buf, | 
|  | 604 | size_t size, loff_t *off) | 
|  | 605 | { | 
|  | 606 | struct clk *clk = file->f_dentry->d_inode->i_private; | 
|  | 607 | char cusecount[128]; | 
|  | 608 | unsigned int len; | 
|  | 609 |  | 
|  | 610 | len = sprintf(cusecount, "%u\n", clk->enabled); | 
|  | 611 | return simple_read_from_buffer(buf, size, off, cusecount, len); | 
|  | 612 | } | 
|  | 613 |  | 
|  | 614 | static ssize_t rate_dbg_read(struct file *file, char __user *buf, | 
|  | 615 | size_t size, loff_t *off) | 
|  | 616 | { | 
|  | 617 | struct clk *clk = file->f_dentry->d_inode->i_private; | 
|  | 618 | char crate[128]; | 
|  | 619 | unsigned int rate; | 
|  | 620 | unsigned int len; | 
|  | 621 |  | 
|  | 622 | rate = clk_get_rate(clk); | 
|  | 623 | len = sprintf(crate, "%u\n", rate); | 
|  | 624 | return simple_read_from_buffer(buf, size, off, crate, len); | 
|  | 625 | } | 
|  | 626 |  | 
|  | 627 | static const struct file_operations usecount_fops = { | 
|  | 628 | .read = usecount_dbg_read, | 
|  | 629 | }; | 
|  | 630 |  | 
|  | 631 | static const struct file_operations set_rate_fops = { | 
|  | 632 | .read = rate_dbg_read, | 
|  | 633 | }; | 
|  | 634 |  | 
|  | 635 | static struct dentry *clk_debugfs_register_dir(struct clk *c, | 
|  | 636 | struct dentry *p_dentry) | 
|  | 637 | { | 
|  | 638 | struct dentry *d, *clk_d, *child, *child_tmp; | 
|  | 639 | char s[255]; | 
|  | 640 | char *p = s; | 
|  | 641 |  | 
|  | 642 | if (c->name == NULL) | 
|  | 643 | p += sprintf(p, "BUG"); | 
|  | 644 | else | 
|  | 645 | p += sprintf(p, "%s", c->name); | 
|  | 646 |  | 
|  | 647 | clk_d = debugfs_create_dir(s, p_dentry); | 
|  | 648 | if (!clk_d) | 
|  | 649 | return NULL; | 
|  | 650 |  | 
|  | 651 | d = debugfs_create_file("usecount", S_IRUGO, | 
|  | 652 | clk_d, c, &usecount_fops); | 
|  | 653 | if (!d) | 
|  | 654 | goto err_out; | 
|  | 655 | d = debugfs_create_file("rate", S_IRUGO, | 
|  | 656 | clk_d, c, &set_rate_fops); | 
|  | 657 | if (!d) | 
|  | 658 | goto err_out; | 
|  | 659 | /* | 
|  | 660 | * TODO : not currently available in ux500 | 
|  | 661 | * d = debugfs_create_x32("flags", S_IRUGO, clk_d, (u32 *)&c->flags); | 
|  | 662 | * if (!d) | 
|  | 663 | *	goto err_out; | 
|  | 664 | */ | 
|  | 665 |  | 
|  | 666 | return clk_d; | 
|  | 667 |  | 
|  | 668 | err_out: | 
|  | 669 | d = clk_d; | 
|  | 670 | list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) | 
|  | 671 | debugfs_remove(child); | 
|  | 672 | debugfs_remove(clk_d); | 
|  | 673 | return NULL; | 
|  | 674 | } | 
|  | 675 |  | 
|  | 676 | static void clk_debugfs_remove_dir(struct dentry *cdentry) | 
|  | 677 | { | 
|  | 678 | struct dentry *d, *child, *child_tmp; | 
|  | 679 |  | 
|  | 680 | d = cdentry; | 
|  | 681 | list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) | 
|  | 682 | debugfs_remove(child); | 
|  | 683 | debugfs_remove(cdentry); | 
|  | 684 | return ; | 
|  | 685 | } | 
|  | 686 |  | 
|  | 687 | static int clk_debugfs_register_one(struct clk *c) | 
|  | 688 | { | 
|  | 689 | struct clk *pa = c->parent_periph; | 
|  | 690 | struct clk *bpa = c->parent_cluster; | 
|  | 691 |  | 
|  | 692 | if (!(bpa && !pa)) { | 
|  | 693 | c->dent = clk_debugfs_register_dir(c, | 
|  | 694 | pa ? pa->dent : clk_debugfs_root); | 
|  | 695 | if (!c->dent) | 
|  | 696 | return -ENOMEM; | 
|  | 697 | } | 
|  | 698 |  | 
|  | 699 | if (bpa) { | 
|  | 700 | c->dent_bus = clk_debugfs_register_dir(c, | 
|  | 701 | bpa->dent_bus ? bpa->dent_bus : bpa->dent); | 
|  | 702 | if ((!c->dent_bus) &&  (c->dent)) { | 
|  | 703 | clk_debugfs_remove_dir(c->dent); | 
|  | 704 | c->dent = NULL; | 
|  | 705 | return -ENOMEM; | 
|  | 706 | } | 
|  | 707 | } | 
|  | 708 | return 0; | 
|  | 709 | } | 
|  | 710 |  | 
|  | 711 | static int clk_debugfs_register(struct clk *c) | 
|  | 712 | { | 
|  | 713 | int err; | 
|  | 714 | struct clk *pa = c->parent_periph; | 
|  | 715 | struct clk *bpa = c->parent_cluster; | 
|  | 716 |  | 
|  | 717 | if (pa && (!pa->dent && !pa->dent_bus)) { | 
|  | 718 | err = clk_debugfs_register(pa); | 
|  | 719 | if (err) | 
|  | 720 | return err; | 
|  | 721 | } | 
|  | 722 |  | 
|  | 723 | if (bpa && (!bpa->dent && !bpa->dent_bus)) { | 
|  | 724 | err = clk_debugfs_register(bpa); | 
|  | 725 | if (err) | 
|  | 726 | return err; | 
|  | 727 | } | 
|  | 728 |  | 
|  | 729 | if ((!c->dent) && (!c->dent_bus)) { | 
|  | 730 | err = clk_debugfs_register_one(c); | 
|  | 731 | if (err) | 
|  | 732 | return err; | 
|  | 733 | } | 
|  | 734 | return 0; | 
|  | 735 | } | 
|  | 736 |  | 
|  | 737 | static int __init clk_debugfs_init(void) | 
|  | 738 | { | 
|  | 739 | struct clk *c; | 
|  | 740 | struct dentry *d; | 
|  | 741 | int err; | 
|  | 742 |  | 
|  | 743 | d = debugfs_create_dir("clock", NULL); | 
|  | 744 | if (!d) | 
|  | 745 | return -ENOMEM; | 
|  | 746 | clk_debugfs_root = d; | 
|  | 747 |  | 
|  | 748 | list_for_each_entry(c, &clk_list, list) { | 
|  | 749 | err = clk_debugfs_register(c); | 
|  | 750 | if (err) | 
|  | 751 | goto err_out; | 
|  | 752 | } | 
|  | 753 | return 0; | 
|  | 754 | err_out: | 
|  | 755 | debugfs_remove_recursive(clk_debugfs_root); | 
|  | 756 | return err; | 
|  | 757 | } | 
|  | 758 |  | 
|  | 759 | late_initcall(clk_debugfs_init); | 
|  | 760 | #endif /* defined(CONFIG_DEBUG_FS) */ | 
|  | 761 |  | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 762 | int __init clk_init(void) | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 763 | { | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 764 | if (cpu_is_u8500ed()) { | 
|  | 765 | clk_prcmu_ops.enable = clk_prcmu_ed_enable; | 
|  | 766 | clk_prcmu_ops.disable = clk_prcmu_ed_disable; | 
| Linus Walleij | ba327b1 | 2010-05-26 07:38:54 +0100 | [diff] [blame] | 767 | clk_per6clk.rate = 100000000; | 
| Rabin Vincent | 591d8dd | 2010-05-03 08:46:51 +0100 | [diff] [blame] | 768 | } else if (cpu_is_u5500()) { | 
|  | 769 | /* Clock tree for U5500 not implemented yet */ | 
|  | 770 | clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; | 
|  | 771 | clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; | 
| Per Forlin | bab263e | 2010-12-05 12:49:03 +0100 | [diff] [blame] | 772 | clk_uartclk.rate = 36360000; | 
|  | 773 | clk_sdmmcclk.rate = 99900000; | 
| Rabin Vincent | 1df20af | 2010-03-01 05:07:47 +0100 | [diff] [blame] | 774 | } | 
|  | 775 |  | 
|  | 776 | clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); | 
|  | 777 | if (cpu_is_u8500ed()) | 
|  | 778 | clkdev_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks)); | 
|  | 779 | else | 
|  | 780 | clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); | 
|  | 781 |  | 
| Vincent Guittot | 763eef8 | 2010-12-03 18:18:39 +0100 | [diff] [blame] | 782 | #ifdef CONFIG_DEBUG_FS | 
|  | 783 | clk_debugfs_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); | 
|  | 784 | if (cpu_is_u8500ed()) | 
|  | 785 | clk_debugfs_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks)); | 
|  | 786 | else | 
|  | 787 | clk_debugfs_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); | 
|  | 788 | #endif | 
| Srinidhi Kasagar | c6b503c | 2009-11-28 08:15:01 +0100 | [diff] [blame] | 789 | return 0; | 
|  | 790 | } |