1/* linux/arch/arm/mach-s5pv210/clock.c 2 * 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 4 * http://www.samsung.com/ 5 * 6 * S5PV210 - Clock support 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11*/ 12 13#include <linux/init.h> 14#include <linux/module.h> 15#include <linux/kernel.h> 16#include <linux/list.h> 17#include <linux/errno.h> 18#include <linux/err.h> 19#include <linux/clk.h> 20#include <linux/device.h> 21#include <linux/io.h> 22 23#include <mach/map.h> 24 25#include <plat/cpu-freq.h> 26#include <mach/regs-clock.h> 27#include <plat/clock.h> 28#include <plat/cpu.h> 29#include <plat/pll.h> 30#include <plat/s5p-clock.h> 31#include <plat/clock-clksrc.h> 32 33#include "common.h" 34 35static unsigned long xtal; 36 37static struct clksrc_clk clk_mout_apll = { 38 .clk = { 39 .name = "mout_apll", 40 }, 41 .sources = &clk_src_apll, 42 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 }, 43}; 44 45static struct clksrc_clk clk_mout_epll = { 46 .clk = { 47 .name = "mout_epll", 48 }, 49 .sources = &clk_src_epll, 50 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 }, 51}; 52 53static struct clksrc_clk clk_mout_mpll = { 54 .clk = { 55 .name = "mout_mpll", 56 }, 57 .sources = &clk_src_mpll, 58 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 }, 59}; 60 61static struct clk *clkset_armclk_list[] = { 62 [0] = &clk_mout_apll.clk, 63 [1] = &clk_mout_mpll.clk, 64}; 65 66static struct clksrc_sources clkset_armclk = { 67 .sources = clkset_armclk_list, 68 .nr_sources = ARRAY_SIZE(clkset_armclk_list), 69}; 70 71static struct clksrc_clk clk_armclk = { 72 .clk = { 73 .name = "armclk", 74 }, 75 .sources = &clkset_armclk, 76 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 }, 77 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 }, 78}; 79 80static struct clksrc_clk clk_hclk_msys = { 81 .clk = { 82 .name = "hclk_msys", 83 .parent = &clk_armclk.clk, 84 }, 85 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 }, 86}; 87 88static struct clksrc_clk clk_pclk_msys = { 89 .clk = { 90 .name = "pclk_msys", 91 .parent = &clk_hclk_msys.clk, 92 }, 93 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 }, 94}; 95 96static struct clksrc_clk clk_sclk_a2m = { 97 .clk = { 98 .name = "sclk_a2m", 99 .parent = &clk_mout_apll.clk, 100 }, 101 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 }, 102}; 103 104static struct clk *clkset_hclk_sys_list[] = { 105 [0] = &clk_mout_mpll.clk, 106 [1] = &clk_sclk_a2m.clk, 107}; 108 109static struct clksrc_sources clkset_hclk_sys = { 110 .sources = clkset_hclk_sys_list, 111 .nr_sources = ARRAY_SIZE(clkset_hclk_sys_list), 112}; 113 114static struct clksrc_clk clk_hclk_dsys = { 115 .clk = { 116 .name = "hclk_dsys", 117 }, 118 .sources = &clkset_hclk_sys, 119 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 }, 120 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 }, 121}; 122 123static struct clksrc_clk clk_pclk_dsys = { 124 .clk = { 125 .name = "pclk_dsys", 126 .parent = &clk_hclk_dsys.clk, 127 }, 128 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 }, 129}; 130 131static struct clksrc_clk clk_hclk_psys = { 132 .clk = { 133 .name = "hclk_psys", 134 }, 135 .sources = &clkset_hclk_sys, 136 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 }, 137 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 }, 138}; 139 140static struct clksrc_clk clk_pclk_psys = { 141 .clk = { 142 .name = "pclk_psys", 143 .parent = &clk_hclk_psys.clk, 144 }, 145 .reg_div = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 }, 146}; 147 148static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable) 149{ 150 return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable); 151} 152 153static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable) 154{ 155 return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable); 156} 157 158static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable) 159{ 160 return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable); 161} 162 163static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable) 164{ 165 return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); 166} 167 168static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable) 169{ 170 return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable); 171} 172 173static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable) 174{ 175 return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable); 176} 177 178static int s5pv210_clk_hdmiphy_ctrl(struct clk *clk, int enable) 179{ 180 return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable); 181} 182 183static int exynos4_clk_dac_ctrl(struct clk *clk, int enable) 184{ 185 return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable); 186} 187 188static struct clk clk_sclk_hdmi27m = { 189 .name = "sclk_hdmi27m", 190 .rate = 27000000, 191}; 192 193static struct clk clk_sclk_hdmiphy = { 194 .name = "sclk_hdmiphy", 195}; 196 197static struct clk clk_sclk_usbphy0 = { 198 .name = "sclk_usbphy0", 199}; 200 201static struct clk clk_sclk_usbphy1 = { 202 .name = "sclk_usbphy1", 203}; 204 205static struct clk clk_pcmcdclk0 = { 206 .name = "pcmcdclk", 207}; 208 209static struct clk clk_pcmcdclk1 = { 210 .name = "pcmcdclk", 211}; 212 213static struct clk clk_pcmcdclk2 = { 214 .name = "pcmcdclk", 215}; 216 217static struct clk dummy_apb_pclk = { 218 .name = "apb_pclk", 219 .id = -1, 220}; 221 222static struct clk *clkset_vpllsrc_list[] = { 223 [0] = &clk_fin_vpll, 224 [1] = &clk_sclk_hdmi27m, 225}; 226 227static struct clksrc_sources clkset_vpllsrc = { 228 .sources = clkset_vpllsrc_list, 229 .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list), 230}; 231 232static struct clksrc_clk clk_vpllsrc = { 233 .clk = { 234 .name = "vpll_src", 235 .enable = s5pv210_clk_mask0_ctrl, 236 .ctrlbit = (1 << 7), 237 }, 238 .sources = &clkset_vpllsrc, 239 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 }, 240}; 241 242static struct clk *clkset_sclk_vpll_list[] = { 243 [0] = &clk_vpllsrc.clk, 244 [1] = &clk_fout_vpll, 245}; 246 247static struct clksrc_sources clkset_sclk_vpll = { 248 .sources = clkset_sclk_vpll_list, 249 .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list), 250}; 251 252static struct clksrc_clk clk_sclk_vpll = { 253 .clk = { 254 .name = "sclk_vpll", 255 }, 256 .sources = &clkset_sclk_vpll, 257 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 }, 258}; 259 260static struct clk *clkset_moutdmc0src_list[] = { 261 [0] = &clk_sclk_a2m.clk, 262 [1] = &clk_mout_mpll.clk, 263 [2] = NULL, 264 [3] = NULL, 265}; 266 267static struct clksrc_sources clkset_moutdmc0src = { 268 .sources = clkset_moutdmc0src_list, 269 .nr_sources = ARRAY_SIZE(clkset_moutdmc0src_list), 270}; 271 272static struct clksrc_clk clk_mout_dmc0 = { 273 .clk = { 274 .name = "mout_dmc0", 275 }, 276 .sources = &clkset_moutdmc0src, 277 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 }, 278}; 279 280static struct clksrc_clk clk_sclk_dmc0 = { 281 .clk = { 282 .name = "sclk_dmc0", 283 .parent = &clk_mout_dmc0.clk, 284 }, 285 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 }, 286}; 287 288static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk) 289{ 290 return clk_get_rate(clk->parent) / 2; 291} 292 293static struct clk_ops clk_hclk_imem_ops = { 294 .get_rate = s5pv210_clk_imem_get_rate, 295}; 296 297static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk) 298{ 299 return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); 300} 301 302static struct clk_ops clk_fout_apll_ops = { 303 .get_rate = s5pv210_clk_fout_apll_get_rate, 304}; 305 306static struct clk init_clocks_off[] = { 307 { 308 .name = "dma", 309 .devname = "dma-pl330.0", 310 .parent = &clk_hclk_psys.clk, 311 .enable = s5pv210_clk_ip0_ctrl, 312 .ctrlbit = (1 << 3), 313 }, { 314 .name = "dma", 315 .devname = "dma-pl330.1", 316 .parent = &clk_hclk_psys.clk, 317 .enable = s5pv210_clk_ip0_ctrl, 318 .ctrlbit = (1 << 4), 319 }, { 320 .name = "rot", 321 .parent = &clk_hclk_dsys.clk, 322 .enable = s5pv210_clk_ip0_ctrl, 323 .ctrlbit = (1<<29), 324 }, { 325 .name = "fimc", 326 .devname = "s5pv210-fimc.0", 327 .parent = &clk_hclk_dsys.clk, 328 .enable = s5pv210_clk_ip0_ctrl, 329 .ctrlbit = (1 << 24), 330 }, { 331 .name = "fimc", 332 .devname = "s5pv210-fimc.1", 333 .parent = &clk_hclk_dsys.clk, 334 .enable = s5pv210_clk_ip0_ctrl, 335 .ctrlbit = (1 << 25), 336 }, { 337 .name = "fimc", 338 .devname = "s5pv210-fimc.2", 339 .parent = &clk_hclk_dsys.clk, 340 .enable = s5pv210_clk_ip0_ctrl, 341 .ctrlbit = (1 << 26), 342 }, { 343 .name = "jpeg", 344 .parent = &clk_hclk_dsys.clk, 345 .enable = s5pv210_clk_ip0_ctrl, 346 .ctrlbit = (1 << 28), 347 }, { 348 .name = "mfc", 349 .devname = "s5p-mfc", 350 .parent = &clk_pclk_psys.clk, 351 .enable = s5pv210_clk_ip0_ctrl, 352 .ctrlbit = (1 << 16), 353 }, { 354 .name = "dac", 355 .devname = "s5p-sdo", 356 .parent = &clk_hclk_dsys.clk, 357 .enable = s5pv210_clk_ip1_ctrl, 358 .ctrlbit = (1 << 10), 359 }, { 360 .name = "mixer", 361 .devname = "s5p-mixer", 362 .parent = &clk_hclk_dsys.clk, 363 .enable = s5pv210_clk_ip1_ctrl, 364 .ctrlbit = (1 << 9), 365 }, { 366 .name = "vp", 367 .devname = "s5p-mixer", 368 .parent = &clk_hclk_dsys.clk, 369 .enable = s5pv210_clk_ip1_ctrl, 370 .ctrlbit = (1 << 8), 371 }, { 372 .name = "hdmi", 373 .devname = "s5pv210-hdmi", 374 .parent = &clk_hclk_dsys.clk, 375 .enable = s5pv210_clk_ip1_ctrl, 376 .ctrlbit = (1 << 11), 377 }, { 378 .name = "hdmiphy", 379 .devname = "s5pv210-hdmi", 380 .enable = s5pv210_clk_hdmiphy_ctrl, 381 .ctrlbit = (1 << 0), 382 }, { 383 .name = "dacphy", 384 .devname = "s5p-sdo", 385 .enable = exynos4_clk_dac_ctrl, 386 .ctrlbit = (1 << 0), 387 }, { 388 .name = "otg", 389 .parent = &clk_hclk_psys.clk, 390 .enable = s5pv210_clk_ip1_ctrl, 391 .ctrlbit = (1<<16), 392 }, { 393 .name = "usb-host", 394 .parent = &clk_hclk_psys.clk, 395 .enable = s5pv210_clk_ip1_ctrl, 396 .ctrlbit = (1<<17), 397 }, { 398 .name = "lcd", 399 .parent = &clk_hclk_dsys.clk, 400 .enable = s5pv210_clk_ip1_ctrl, 401 .ctrlbit = (1<<0), 402 }, { 403 .name = "cfcon", 404 .parent = &clk_hclk_psys.clk, 405 .enable = s5pv210_clk_ip1_ctrl, 406 .ctrlbit = (1<<25), 407 }, { 408 .name = "systimer", 409 .parent = &clk_pclk_psys.clk, 410 .enable = s5pv210_clk_ip3_ctrl, 411 .ctrlbit = (1<<16), 412 }, { 413 .name = "watchdog", 414 .parent = &clk_pclk_psys.clk, 415 .enable = s5pv210_clk_ip3_ctrl, 416 .ctrlbit = (1<<22), 417 }, { 418 .name = "rtc", 419 .parent = &clk_pclk_psys.clk, 420 .enable = s5pv210_clk_ip3_ctrl, 421 .ctrlbit = (1<<15), 422 }, { 423 .name = "i2c", 424 .devname = "s3c2440-i2c.0", 425 .parent = &clk_pclk_psys.clk, 426 .enable = s5pv210_clk_ip3_ctrl, 427 .ctrlbit = (1<<7), 428 }, { 429 .name = "i2c", 430 .devname = "s3c2440-i2c.1", 431 .parent = &clk_pclk_psys.clk, 432 .enable = s5pv210_clk_ip3_ctrl, 433 .ctrlbit = (1 << 10), 434 }, { 435 .name = "i2c", 436 .devname = "s3c2440-i2c.2", 437 .parent = &clk_pclk_psys.clk, 438 .enable = s5pv210_clk_ip3_ctrl, 439 .ctrlbit = (1<<9), 440 }, { 441 .name = "i2c", 442 .devname = "s3c2440-hdmiphy-i2c", 443 .parent = &clk_pclk_psys.clk, 444 .enable = s5pv210_clk_ip3_ctrl, 445 .ctrlbit = (1 << 11), 446 }, { 447 .name = "spi", 448 .devname = "s3c64xx-spi.0", 449 .parent = &clk_pclk_psys.clk, 450 .enable = s5pv210_clk_ip3_ctrl, 451 .ctrlbit = (1<<12), 452 }, { 453 .name = "spi", 454 .devname = "s3c64xx-spi.1", 455 .parent = &clk_pclk_psys.clk, 456 .enable = s5pv210_clk_ip3_ctrl, 457 .ctrlbit = (1<<13), 458 }, { 459 .name = "spi", 460 .devname = "s3c64xx-spi.2", 461 .parent = &clk_pclk_psys.clk, 462 .enable = s5pv210_clk_ip3_ctrl, 463 .ctrlbit = (1<<14), 464 }, { 465 .name = "timers", 466 .parent = &clk_pclk_psys.clk, 467 .enable = s5pv210_clk_ip3_ctrl, 468 .ctrlbit = (1<<23), 469 }, { 470 .name = "adc", 471 .parent = &clk_pclk_psys.clk, 472 .enable = s5pv210_clk_ip3_ctrl, 473 .ctrlbit = (1<<24), 474 }, { 475 .name = "keypad", 476 .parent = &clk_pclk_psys.clk, 477 .enable = s5pv210_clk_ip3_ctrl, 478 .ctrlbit = (1<<21), 479 }, { 480 .name = "iis", 481 .devname = "samsung-i2s.0", 482 .parent = &clk_p, 483 .enable = s5pv210_clk_ip3_ctrl, 484 .ctrlbit = (1<<4), 485 }, { 486 .name = "iis", 487 .devname = "samsung-i2s.1", 488 .parent = &clk_p, 489 .enable = s5pv210_clk_ip3_ctrl, 490 .ctrlbit = (1 << 5), 491 }, { 492 .name = "iis", 493 .devname = "samsung-i2s.2", 494 .parent = &clk_p, 495 .enable = s5pv210_clk_ip3_ctrl, 496 .ctrlbit = (1 << 6), 497 }, { 498 .name = "spdif", 499 .parent = &clk_p, 500 .enable = s5pv210_clk_ip3_ctrl, 501 .ctrlbit = (1 << 0), 502 }, 503}; 504 505static struct clk init_clocks[] = { 506 { 507 .name = "hclk_imem", 508 .parent = &clk_hclk_msys.clk, 509 .ctrlbit = (1 << 5), 510 .enable = s5pv210_clk_ip0_ctrl, 511 .ops = &clk_hclk_imem_ops, 512 }, { 513 .name = "uart", 514 .devname = "s5pv210-uart.0", 515 .parent = &clk_pclk_psys.clk, 516 .enable = s5pv210_clk_ip3_ctrl, 517 .ctrlbit = (1 << 17), 518 }, { 519 .name = "uart", 520 .devname = "s5pv210-uart.1", 521 .parent = &clk_pclk_psys.clk, 522 .enable = s5pv210_clk_ip3_ctrl, 523 .ctrlbit = (1 << 18), 524 }, { 525 .name = "uart", 526 .devname = "s5pv210-uart.2", 527 .parent = &clk_pclk_psys.clk, 528 .enable = s5pv210_clk_ip3_ctrl, 529 .ctrlbit = (1 << 19), 530 }, { 531 .name = "uart", 532 .devname = "s5pv210-uart.3", 533 .parent = &clk_pclk_psys.clk, 534 .enable = s5pv210_clk_ip3_ctrl, 535 .ctrlbit = (1 << 20), 536 }, { 537 .name = "sromc", 538 .parent = &clk_hclk_psys.clk, 539 .enable = s5pv210_clk_ip1_ctrl, 540 .ctrlbit = (1 << 26), 541 }, 542}; 543 544static struct clk clk_hsmmc0 = { 545 .name = "hsmmc", 546 .devname = "s3c-sdhci.0", 547 .parent = &clk_hclk_psys.clk, 548 .enable = s5pv210_clk_ip2_ctrl, 549 .ctrlbit = (1<<16), 550}; 551 552static struct clk clk_hsmmc1 = { 553 .name = "hsmmc", 554 .devname = "s3c-sdhci.1", 555 .parent = &clk_hclk_psys.clk, 556 .enable = s5pv210_clk_ip2_ctrl, 557 .ctrlbit = (1<<17), 558}; 559 560static struct clk clk_hsmmc2 = { 561 .name = "hsmmc", 562 .devname = "s3c-sdhci.2", 563 .parent = &clk_hclk_psys.clk, 564 .enable = s5pv210_clk_ip2_ctrl, 565 .ctrlbit = (1<<18), 566}; 567 568static struct clk clk_hsmmc3 = { 569 .name = "hsmmc", 570 .devname = "s3c-sdhci.3", 571 .parent = &clk_hclk_psys.clk, 572 .enable = s5pv210_clk_ip2_ctrl, 573 .ctrlbit = (1<<19), 574}; 575 576static struct clk *clkset_uart_list[] = { 577 [6] = &clk_mout_mpll.clk, 578 [7] = &clk_mout_epll.clk, 579}; 580 581static struct clksrc_sources clkset_uart = { 582 .sources = clkset_uart_list, 583 .nr_sources = ARRAY_SIZE(clkset_uart_list), 584}; 585 586static struct clk *clkset_group1_list[] = { 587 [0] = &clk_sclk_a2m.clk, 588 [1] = &clk_mout_mpll.clk, 589 [2] = &clk_mout_epll.clk, 590 [3] = &clk_sclk_vpll.clk, 591}; 592 593static struct clksrc_sources clkset_group1 = { 594 .sources = clkset_group1_list, 595 .nr_sources = ARRAY_SIZE(clkset_group1_list), 596}; 597 598static struct clk *clkset_sclk_onenand_list[] = { 599 [0] = &clk_hclk_psys.clk, 600 [1] = &clk_hclk_dsys.clk, 601}; 602 603static struct clksrc_sources clkset_sclk_onenand = { 604 .sources = clkset_sclk_onenand_list, 605 .nr_sources = ARRAY_SIZE(clkset_sclk_onenand_list), 606}; 607 608static struct clk *clkset_sclk_dac_list[] = { 609 [0] = &clk_sclk_vpll.clk, 610 [1] = &clk_sclk_hdmiphy, 611}; 612 613static struct clksrc_sources clkset_sclk_dac = { 614 .sources = clkset_sclk_dac_list, 615 .nr_sources = ARRAY_SIZE(clkset_sclk_dac_list), 616}; 617 618static struct clksrc_clk clk_sclk_dac = { 619 .clk = { 620 .name = "sclk_dac", 621 .enable = s5pv210_clk_mask0_ctrl, 622 .ctrlbit = (1 << 2), 623 }, 624 .sources = &clkset_sclk_dac, 625 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 }, 626}; 627 628static struct clksrc_clk clk_sclk_pixel = { 629 .clk = { 630 .name = "sclk_pixel", 631 .parent = &clk_sclk_vpll.clk, 632 }, 633 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4}, 634}; 635 636static struct clk *clkset_sclk_hdmi_list[] = { 637 [0] = &clk_sclk_pixel.clk, 638 [1] = &clk_sclk_hdmiphy, 639}; 640 641static struct clksrc_sources clkset_sclk_hdmi = { 642 .sources = clkset_sclk_hdmi_list, 643 .nr_sources = ARRAY_SIZE(clkset_sclk_hdmi_list), 644}; 645 646static struct clksrc_clk clk_sclk_hdmi = { 647 .clk = { 648 .name = "sclk_hdmi", 649 .enable = s5pv210_clk_mask0_ctrl, 650 .ctrlbit = (1 << 0), 651 }, 652 .sources = &clkset_sclk_hdmi, 653 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 }, 654}; 655 656static struct clk *clkset_sclk_mixer_list[] = { 657 [0] = &clk_sclk_dac.clk, 658 [1] = &clk_sclk_hdmi.clk, 659}; 660 661static struct clksrc_sources clkset_sclk_mixer = { 662 .sources = clkset_sclk_mixer_list, 663 .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list), 664}; 665 666static struct clksrc_clk clk_sclk_mixer = { 667 .clk = { 668 .name = "sclk_mixer", 669 .enable = s5pv210_clk_mask0_ctrl, 670 .ctrlbit = (1 << 1), 671 }, 672 .sources = &clkset_sclk_mixer, 673 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 }, 674}; 675 676static struct clksrc_clk *sclk_tv[] = { 677 &clk_sclk_dac, 678 &clk_sclk_pixel, 679 &clk_sclk_hdmi, 680 &clk_sclk_mixer, 681}; 682 683static struct clk *clkset_sclk_audio0_list[] = { 684 [0] = &clk_ext_xtal_mux, 685 [1] = &clk_pcmcdclk0, 686 [2] = &clk_sclk_hdmi27m, 687 [3] = &clk_sclk_usbphy0, 688 [4] = &clk_sclk_usbphy1, 689 [5] = &clk_sclk_hdmiphy, 690 [6] = &clk_mout_mpll.clk, 691 [7] = &clk_mout_epll.clk, 692 [8] = &clk_sclk_vpll.clk, 693}; 694 695static struct clksrc_sources clkset_sclk_audio0 = { 696 .sources = clkset_sclk_audio0_list, 697 .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list), 698}; 699 700static struct clksrc_clk clk_sclk_audio0 = { 701 .clk = { 702 .name = "sclk_audio", 703 .devname = "soc-audio.0", 704 .enable = s5pv210_clk_mask0_ctrl, 705 .ctrlbit = (1 << 24), 706 }, 707 .sources = &clkset_sclk_audio0, 708 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 }, 709 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 }, 710}; 711 712static struct clk *clkset_sclk_audio1_list[] = { 713 [0] = &clk_ext_xtal_mux, 714 [1] = &clk_pcmcdclk1, 715 [2] = &clk_sclk_hdmi27m, 716 [3] = &clk_sclk_usbphy0, 717 [4] = &clk_sclk_usbphy1, 718 [5] = &clk_sclk_hdmiphy, 719 [6] = &clk_mout_mpll.clk, 720 [7] = &clk_mout_epll.clk, 721 [8] = &clk_sclk_vpll.clk, 722}; 723 724static struct clksrc_sources clkset_sclk_audio1 = { 725 .sources = clkset_sclk_audio1_list, 726 .nr_sources = ARRAY_SIZE(clkset_sclk_audio1_list), 727}; 728 729static struct clksrc_clk clk_sclk_audio1 = { 730 .clk = { 731 .name = "sclk_audio", 732 .devname = "soc-audio.1", 733 .enable = s5pv210_clk_mask0_ctrl, 734 .ctrlbit = (1 << 25), 735 }, 736 .sources = &clkset_sclk_audio1, 737 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 }, 738 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 }, 739}; 740 741static struct clk *clkset_sclk_audio2_list[] = { 742 [0] = &clk_ext_xtal_mux, 743 [1] = &clk_pcmcdclk0, 744 [2] = &clk_sclk_hdmi27m, 745 [3] = &clk_sclk_usbphy0, 746 [4] = &clk_sclk_usbphy1, 747 [5] = &clk_sclk_hdmiphy, 748 [6] = &clk_mout_mpll.clk, 749 [7] = &clk_mout_epll.clk, 750 [8] = &clk_sclk_vpll.clk, 751}; 752 753static struct clksrc_sources clkset_sclk_audio2 = { 754 .sources = clkset_sclk_audio2_list, 755 .nr_sources = ARRAY_SIZE(clkset_sclk_audio2_list), 756}; 757 758static struct clksrc_clk clk_sclk_audio2 = { 759 .clk = { 760 .name = "sclk_audio", 761 .devname = "soc-audio.2", 762 .enable = s5pv210_clk_mask0_ctrl, 763 .ctrlbit = (1 << 26), 764 }, 765 .sources = &clkset_sclk_audio2, 766 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 }, 767 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 }, 768}; 769 770static struct clk *clkset_sclk_spdif_list[] = { 771 [0] = &clk_sclk_audio0.clk, 772 [1] = &clk_sclk_audio1.clk, 773 [2] = &clk_sclk_audio2.clk, 774}; 775 776static struct clksrc_sources clkset_sclk_spdif = { 777 .sources = clkset_sclk_spdif_list, 778 .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list), 779}; 780 781static struct clksrc_clk clk_sclk_spdif = { 782 .clk = { 783 .name = "sclk_spdif", 784 .enable = s5pv210_clk_mask0_ctrl, 785 .ctrlbit = (1 << 27), 786 .ops = &s5p_sclk_spdif_ops, 787 }, 788 .sources = &clkset_sclk_spdif, 789 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 }, 790}; 791 792static struct clk *clkset_group2_list[] = { 793 [0] = &clk_ext_xtal_mux, 794 [1] = &clk_xusbxti, 795 [2] = &clk_sclk_hdmi27m, 796 [3] = &clk_sclk_usbphy0, 797 [4] = &clk_sclk_usbphy1, 798 [5] = &clk_sclk_hdmiphy, 799 [6] = &clk_mout_mpll.clk, 800 [7] = &clk_mout_epll.clk, 801 [8] = &clk_sclk_vpll.clk, 802}; 803 804static struct clksrc_sources clkset_group2 = { 805 .sources = clkset_group2_list, 806 .nr_sources = ARRAY_SIZE(clkset_group2_list), 807}; 808 809static struct clksrc_clk clksrcs[] = { 810 { 811 .clk = { 812 .name = "sclk_dmc", 813 }, 814 .sources = &clkset_group1, 815 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 }, 816 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 }, 817 }, { 818 .clk = { 819 .name = "sclk_onenand", 820 }, 821 .sources = &clkset_sclk_onenand, 822 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 }, 823 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 }, 824 }, { 825 .clk = { 826 .name = "sclk_fimc", 827 .devname = "s5pv210-fimc.0", 828 .enable = s5pv210_clk_mask1_ctrl, 829 .ctrlbit = (1 << 2), 830 }, 831 .sources = &clkset_group2, 832 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 }, 833 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 }, 834 }, { 835 .clk = { 836 .name = "sclk_fimc", 837 .devname = "s5pv210-fimc.1", 838 .enable = s5pv210_clk_mask1_ctrl, 839 .ctrlbit = (1 << 3), 840 }, 841 .sources = &clkset_group2, 842 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 }, 843 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 }, 844 }, { 845 .clk = { 846 .name = "sclk_fimc", 847 .devname = "s5pv210-fimc.2", 848 .enable = s5pv210_clk_mask1_ctrl, 849 .ctrlbit = (1 << 4), 850 }, 851 .sources = &clkset_group2, 852 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 }, 853 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 }, 854 }, { 855 .clk = { 856 .name = "sclk_cam0", 857 .enable = s5pv210_clk_mask0_ctrl, 858 .ctrlbit = (1 << 3), 859 }, 860 .sources = &clkset_group2, 861 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 }, 862 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 }, 863 }, { 864 .clk = { 865 .name = "sclk_cam1", 866 .enable = s5pv210_clk_mask0_ctrl, 867 .ctrlbit = (1 << 4), 868 }, 869 .sources = &clkset_group2, 870 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 }, 871 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 }, 872 }, { 873 .clk = { 874 .name = "sclk_fimd", 875 .enable = s5pv210_clk_mask0_ctrl, 876 .ctrlbit = (1 << 5), 877 }, 878 .sources = &clkset_group2, 879 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 }, 880 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 }, 881 }, { 882 .clk = { 883 .name = "sclk_mfc", 884 .devname = "s5p-mfc", 885 .enable = s5pv210_clk_ip0_ctrl, 886 .ctrlbit = (1 << 16), 887 }, 888 .sources = &clkset_group1, 889 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 }, 890 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, 891 }, { 892 .clk = { 893 .name = "sclk_g2d", 894 .enable = s5pv210_clk_ip0_ctrl, 895 .ctrlbit = (1 << 12), 896 }, 897 .sources = &clkset_group1, 898 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 }, 899 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 }, 900 }, { 901 .clk = { 902 .name = "sclk_g3d", 903 .enable = s5pv210_clk_ip0_ctrl, 904 .ctrlbit = (1 << 8), 905 }, 906 .sources = &clkset_group1, 907 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 }, 908 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, 909 }, { 910 .clk = { 911 .name = "sclk_csis", 912 .enable = s5pv210_clk_mask0_ctrl, 913 .ctrlbit = (1 << 6), 914 }, 915 .sources = &clkset_group2, 916 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 }, 917 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 }, 918 }, { 919 .clk = { 920 .name = "sclk_pwi", 921 .enable = s5pv210_clk_mask0_ctrl, 922 .ctrlbit = (1 << 29), 923 }, 924 .sources = &clkset_group2, 925 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 }, 926 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 }, 927 }, { 928 .clk = { 929 .name = "sclk_pwm", 930 .enable = s5pv210_clk_mask0_ctrl, 931 .ctrlbit = (1 << 19), 932 }, 933 .sources = &clkset_group2, 934 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 }, 935 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 }, 936 }, 937}; 938 939static struct clksrc_clk clk_sclk_uart0 = { 940 .clk = { 941 .name = "uclk1", 942 .devname = "s5pv210-uart.0", 943 .enable = s5pv210_clk_mask0_ctrl, 944 .ctrlbit = (1 << 12), 945 }, 946 .sources = &clkset_uart, 947 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 }, 948 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, 949}; 950 951static struct clksrc_clk clk_sclk_uart1 = { 952 .clk = { 953 .name = "uclk1", 954 .devname = "s5pv210-uart.1", 955 .enable = s5pv210_clk_mask0_ctrl, 956 .ctrlbit = (1 << 13), 957 }, 958 .sources = &clkset_uart, 959 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 }, 960 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, 961}; 962 963static struct clksrc_clk clk_sclk_uart2 = { 964 .clk = { 965 .name = "uclk1", 966 .devname = "s5pv210-uart.2", 967 .enable = s5pv210_clk_mask0_ctrl, 968 .ctrlbit = (1 << 14), 969 }, 970 .sources = &clkset_uart, 971 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 }, 972 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 }, 973}; 974 975static struct clksrc_clk clk_sclk_uart3 = { 976 .clk = { 977 .name = "uclk1", 978 .devname = "s5pv210-uart.3", 979 .enable = s5pv210_clk_mask0_ctrl, 980 .ctrlbit = (1 << 15), 981 }, 982 .sources = &clkset_uart, 983 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 }, 984 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 }, 985}; 986 987static struct clksrc_clk clk_sclk_mmc0 = { 988 .clk = { 989 .name = "sclk_mmc", 990 .devname = "s3c-sdhci.0", 991 .enable = s5pv210_clk_mask0_ctrl, 992 .ctrlbit = (1 << 8), 993 }, 994 .sources = &clkset_group2, 995 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 }, 996 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 }, 997}; 998 999static struct clksrc_clk clk_sclk_mmc1 = { 1000 .clk = { 1001 .name = "sclk_mmc", 1002 .devname = "s3c-sdhci.1", 1003 .enable = s5pv210_clk_mask0_ctrl, 1004 .ctrlbit = (1 << 9), 1005 }, 1006 .sources = &clkset_group2, 1007 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 }, 1008 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 }, 1009}; 1010 1011static struct clksrc_clk clk_sclk_mmc2 = { 1012 .clk = { 1013 .name = "sclk_mmc", 1014 .devname = "s3c-sdhci.2", 1015 .enable = s5pv210_clk_mask0_ctrl, 1016 .ctrlbit = (1 << 10), 1017 }, 1018 .sources = &clkset_group2, 1019 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 }, 1020 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 }, 1021}; 1022 1023static struct clksrc_clk clk_sclk_mmc3 = { 1024 .clk = { 1025 .name = "sclk_mmc", 1026 .devname = "s3c-sdhci.3", 1027 .enable = s5pv210_clk_mask0_ctrl, 1028 .ctrlbit = (1 << 11), 1029 }, 1030 .sources = &clkset_group2, 1031 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 }, 1032 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, 1033}; 1034 1035static struct clksrc_clk clk_sclk_spi0 = { 1036 .clk = { 1037 .name = "sclk_spi", 1038 .devname = "s3c64xx-spi.0", 1039 .enable = s5pv210_clk_mask0_ctrl, 1040 .ctrlbit = (1 << 16), 1041 }, 1042 .sources = &clkset_group2, 1043 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 }, 1044 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 }, 1045 }; 1046 1047static struct clksrc_clk clk_sclk_spi1 = { 1048 .clk = { 1049 .name = "sclk_spi", 1050 .devname = "s3c64xx-spi.1", 1051 .enable = s5pv210_clk_mask0_ctrl, 1052 .ctrlbit = (1 << 17), 1053 }, 1054 .sources = &clkset_group2, 1055 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 }, 1056 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 }, 1057 }; 1058 1059 1060static struct clksrc_clk *clksrc_cdev[] = { 1061 &clk_sclk_uart0, 1062 &clk_sclk_uart1, 1063 &clk_sclk_uart2, 1064 &clk_sclk_uart3, 1065 &clk_sclk_mmc0, 1066 &clk_sclk_mmc1, 1067 &clk_sclk_mmc2, 1068 &clk_sclk_mmc3, 1069 &clk_sclk_spi0, 1070 &clk_sclk_spi1, 1071}; 1072 1073static struct clk *clk_cdev[] = { 1074 &clk_hsmmc0, 1075 &clk_hsmmc1, 1076 &clk_hsmmc2, 1077 &clk_hsmmc3, 1078}; 1079 1080/* Clock initialisation code */ 1081static struct clksrc_clk *sysclks[] = { 1082 &clk_mout_apll, 1083 &clk_mout_epll, 1084 &clk_mout_mpll, 1085 &clk_armclk, 1086 &clk_hclk_msys, 1087 &clk_sclk_a2m, 1088 &clk_hclk_dsys, 1089 &clk_hclk_psys, 1090 &clk_pclk_msys, 1091 &clk_pclk_dsys, 1092 &clk_pclk_psys, 1093 &clk_vpllsrc, 1094 &clk_sclk_vpll, 1095 &clk_mout_dmc0, 1096 &clk_sclk_dmc0, 1097 &clk_sclk_audio0, 1098 &clk_sclk_audio1, 1099 &clk_sclk_audio2, 1100 &clk_sclk_spdif, 1101}; 1102 1103static u32 epll_div[][6] = { 1104 { 48000000, 0, 48, 3, 3, 0 }, 1105 { 96000000, 0, 48, 3, 2, 0 }, 1106 { 144000000, 1, 72, 3, 2, 0 }, 1107 { 192000000, 0, 48, 3, 1, 0 }, 1108 { 288000000, 1, 72, 3, 1, 0 }, 1109 { 32750000, 1, 65, 3, 4, 35127 }, 1110 { 32768000, 1, 65, 3, 4, 35127 }, 1111 { 45158400, 0, 45, 3, 3, 10355 }, 1112 { 45000000, 0, 45, 3, 3, 10355 }, 1113 { 45158000, 0, 45, 3, 3, 10355 }, 1114 { 49125000, 0, 49, 3, 3, 9961 }, 1115 { 49152000, 0, 49, 3, 3, 9961 }, 1116 { 67737600, 1, 67, 3, 3, 48366 }, 1117 { 67738000, 1, 67, 3, 3, 48366 }, 1118 { 73800000, 1, 73, 3, 3, 47710 }, 1119 { 73728000, 1, 73, 3, 3, 47710 }, 1120 { 36000000, 1, 32, 3, 4, 0 }, 1121 { 60000000, 1, 60, 3, 3, 0 }, 1122 { 72000000, 1, 72, 3, 3, 0 }, 1123 { 80000000, 1, 80, 3, 3, 0 }, 1124 { 84000000, 0, 42, 3, 2, 0 }, 1125 { 50000000, 0, 50, 3, 3, 0 }, 1126}; 1127 1128static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate) 1129{ 1130 unsigned int epll_con, epll_con_k; 1131 unsigned int i; 1132 1133 /* Return if nothing changed */ 1134 if (clk->rate == rate) 1135 return 0; 1136 1137 epll_con = __raw_readl(S5P_EPLL_CON); 1138 epll_con_k = __raw_readl(S5P_EPLL_CON1); 1139 1140 epll_con_k &= ~PLL46XX_KDIV_MASK; 1141 epll_con &= ~(1 << 27 | 1142 PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | 1143 PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | 1144 PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); 1145 1146 for (i = 0; i < ARRAY_SIZE(epll_div); i++) { 1147 if (epll_div[i][0] == rate) { 1148 epll_con_k |= epll_div[i][5] << 0; 1149 epll_con |= (epll_div[i][1] << 27 | 1150 epll_div[i][2] << PLL46XX_MDIV_SHIFT | 1151 epll_div[i][3] << PLL46XX_PDIV_SHIFT | 1152 epll_div[i][4] << PLL46XX_SDIV_SHIFT); 1153 break; 1154 } 1155 } 1156 1157 if (i == ARRAY_SIZE(epll_div)) { 1158 printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", 1159 __func__); 1160 return -EINVAL; 1161 } 1162 1163 __raw_writel(epll_con, S5P_EPLL_CON); 1164 __raw_writel(epll_con_k, S5P_EPLL_CON1); 1165 1166 printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n", 1167 clk->rate, rate); 1168 1169 clk->rate = rate; 1170 1171 return 0; 1172} 1173 1174static struct clk_ops s5pv210_epll_ops = { 1175 .set_rate = s5pv210_epll_set_rate, 1176 .get_rate = s5p_epll_get_rate, 1177}; 1178 1179static u32 vpll_div[][5] = { 1180 { 54000000, 3, 53, 3, 0 }, 1181 { 108000000, 3, 53, 2, 0 }, 1182}; 1183 1184static unsigned long s5pv210_vpll_get_rate(struct clk *clk) 1185{ 1186 return clk->rate; 1187} 1188 1189static int s5pv210_vpll_set_rate(struct clk *clk, unsigned long rate) 1190{ 1191 unsigned int vpll_con; 1192 unsigned int i; 1193 1194 /* Return if nothing changed */ 1195 if (clk->rate == rate) 1196 return 0; 1197 1198 vpll_con = __raw_readl(S5P_VPLL_CON); 1199 vpll_con &= ~(0x1 << 27 | \ 1200 PLL90XX_MDIV_MASK << PLL90XX_MDIV_SHIFT | \ 1201 PLL90XX_PDIV_MASK << PLL90XX_PDIV_SHIFT | \ 1202 PLL90XX_SDIV_MASK << PLL90XX_SDIV_SHIFT); 1203 1204 for (i = 0; i < ARRAY_SIZE(vpll_div); i++) { 1205 if (vpll_div[i][0] == rate) { 1206 vpll_con |= vpll_div[i][1] << PLL90XX_PDIV_SHIFT; 1207 vpll_con |= vpll_div[i][2] << PLL90XX_MDIV_SHIFT; 1208 vpll_con |= vpll_div[i][3] << PLL90XX_SDIV_SHIFT; 1209 vpll_con |= vpll_div[i][4] << 27; 1210 break; 1211 } 1212 } 1213 1214 if (i == ARRAY_SIZE(vpll_div)) { 1215 printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n", 1216 __func__); 1217 return -EINVAL; 1218 } 1219 1220 __raw_writel(vpll_con, S5P_VPLL_CON); 1221 1222 /* Wait for VPLL lock */ 1223 while (!(__raw_readl(S5P_VPLL_CON) & (1 << PLL90XX_LOCKED_SHIFT))) 1224 continue; 1225 1226 clk->rate = rate; 1227 return 0; 1228} 1229static struct clk_ops s5pv210_vpll_ops = { 1230 .get_rate = s5pv210_vpll_get_rate, 1231 .set_rate = s5pv210_vpll_set_rate, 1232}; 1233 1234void __init_or_cpufreq s5pv210_setup_clocks(void) 1235{ 1236 struct clk *xtal_clk; 1237 unsigned long vpllsrc; 1238 unsigned long armclk; 1239 unsigned long hclk_msys; 1240 unsigned long hclk_dsys; 1241 unsigned long hclk_psys; 1242 unsigned long pclk_msys; 1243 unsigned long pclk_dsys; 1244 unsigned long pclk_psys; 1245 unsigned long apll; 1246 unsigned long mpll; 1247 unsigned long epll; 1248 unsigned long vpll; 1249 unsigned int ptr; 1250 u32 clkdiv0, clkdiv1; 1251 1252 /* Set functions for clk_fout_epll */ 1253 clk_fout_epll.enable = s5p_epll_enable; 1254 clk_fout_epll.ops = &s5pv210_epll_ops; 1255 1256 printk(KERN_DEBUG "%s: registering clocks\n", __func__); 1257 1258 clkdiv0 = __raw_readl(S5P_CLK_DIV0); 1259 clkdiv1 = __raw_readl(S5P_CLK_DIV1); 1260 1261 printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n", 1262 __func__, clkdiv0, clkdiv1); 1263 1264 xtal_clk = clk_get(NULL, "xtal"); 1265 BUG_ON(IS_ERR(xtal_clk)); 1266 1267 xtal = clk_get_rate(xtal_clk); 1268 clk_put(xtal_clk); 1269 1270 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); 1271 1272 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); 1273 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); 1274 epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON), 1275 __raw_readl(S5P_EPLL_CON1), pll_4600); 1276 vpllsrc = clk_get_rate(&clk_vpllsrc.clk); 1277 vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502); 1278 1279 clk_fout_apll.ops = &clk_fout_apll_ops; 1280 clk_fout_mpll.rate = mpll; 1281 clk_fout_epll.rate = epll; 1282 clk_fout_vpll.ops = &s5pv210_vpll_ops; 1283 clk_fout_vpll.rate = vpll; 1284 1285 printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld", 1286 apll, mpll, epll, vpll); 1287 1288 armclk = clk_get_rate(&clk_armclk.clk); 1289 hclk_msys = clk_get_rate(&clk_hclk_msys.clk); 1290 hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk); 1291 hclk_psys = clk_get_rate(&clk_hclk_psys.clk); 1292 pclk_msys = clk_get_rate(&clk_pclk_msys.clk); 1293 pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk); 1294 pclk_psys = clk_get_rate(&clk_pclk_psys.clk); 1295 1296 printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n" 1297 "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n", 1298 armclk, hclk_msys, hclk_dsys, hclk_psys, 1299 pclk_msys, pclk_dsys, pclk_psys); 1300 1301 clk_f.rate = armclk; 1302 clk_h.rate = hclk_psys; 1303 clk_p.rate = pclk_psys; 1304 1305 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 1306 s3c_set_clksrc(&clksrcs[ptr], true); 1307} 1308 1309static struct clk *clks[] __initdata = { 1310 &clk_sclk_hdmi27m, 1311 &clk_sclk_hdmiphy, 1312 &clk_sclk_usbphy0, 1313 &clk_sclk_usbphy1, 1314 &clk_pcmcdclk0, 1315 &clk_pcmcdclk1, 1316 &clk_pcmcdclk2, 1317}; 1318 1319static struct clk_lookup s5pv210_clk_lookup[] = { 1320 CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p), 1321 CLKDEV_INIT("s5pv210-uart.0", "clk_uart_baud1", &clk_sclk_uart0.clk), 1322 CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk), 1323 CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk), 1324 CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk), 1325 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0), 1326 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1), 1327 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2), 1328 CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.0", &clk_hsmmc3), 1329 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), 1330 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), 1331 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), 1332 CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk), 1333 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), 1334 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), 1335 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), 1336}; 1337 1338void __init s5pv210_register_clocks(void) 1339{ 1340 int ptr; 1341 1342 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); 1343 1344 for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) 1345 s3c_register_clksrc(sysclks[ptr], 1); 1346 1347 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) 1348 s3c_register_clksrc(sclk_tv[ptr], 1); 1349 1350 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++) 1351 s3c_register_clksrc(clksrc_cdev[ptr], 1); 1352 1353 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1354 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1355 1356 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1357 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1358 clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup)); 1359 1360 s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev)); 1361 for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++) 1362 s3c_disable_clocks(clk_cdev[ptr], 1); 1363 1364 s3c24xx_register_clock(&dummy_apb_pclk); 1365 s3c_pwmclk_init(); 1366} 1367