1/* 2 * Memory Setup stuff - taken from blob memsetup.S 3 * 4 * Copyright (C) 2009 Samsung Electronics 5 * Kyungmin Park <kyungmin.park@samsung.com> 6 * 7 * See file CREDITS for list of people who contributed to this 8 * project. 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation; either version 2 of 13 * the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 * MA 02111-1307 USA 24 */ 25 26#include <config.h> 27#include <version.h> 28#include <asm/arch/cpu.h> 29#include <asm/arch/clock.h> 30#include <asm/arch/power.h> 31 32/* 33 * Register usages: 34 * 35 * r5 has zero always 36 * r7 has S5PC100 GPIO base, 0xE0300000 37 * r8 has real GPIO base, 0xE0300000, 0xE0200000 at S5PC100, S5PC110 repectively 38 * r9 has Mobile DDR size, 1 means 1GiB, 2 means 2GiB and so on 39 */ 40 41_TEXT_BASE: 42 .word CONFIG_SYS_TEXT_BASE 43 44 .globl lowlevel_init 45lowlevel_init: 46 mov r11, lr 47 48 /* r5 has always zero */ 49 mov r5, #0 50 51 ldr r7, =S5PC100_GPIO_BASE 52 ldr r8, =S5PC100_GPIO_BASE 53 /* Read CPU ID */ 54 ldr r2, =S5PC110_PRO_ID 55 ldr r0, [r2] 56 mov r1, #0x00010000 57 and r0, r0, r1 58 cmp r0, r5 59 beq 100f 60 ldr r8, =S5PC110_GPIO_BASE 61100: 62 /* Turn on KEY_LED_ON [GPJ4(1)] XMSMWEN */ 63 cmp r7, r8 64 beq skip_check_didle @ Support C110 only 65 66 ldr r0, =S5PC110_RST_STAT 67 ldr r1, [r0] 68 and r1, r1, #0x000D0000 69 cmp r1, #(0x1 << 19) @ DEEPIDLE_WAKEUP 70 beq didle_wakeup 71 cmp r7, r8 72 73skip_check_didle: 74 addeq r0, r8, #0x280 @ S5PC100_GPIO_J4 75 addne r0, r8, #0x2C0 @ S5PC110_GPIO_J4 76 ldr r1, [r0, #0x0] @ GPIO_CON_OFFSET 77 bic r1, r1, #(0xf << 4) @ 1 * 4-bit 78 orr r1, r1, #(0x1 << 4) 79 str r1, [r0, #0x0] @ GPIO_CON_OFFSET 80 81 ldr r1, [r0, #0x4] @ GPIO_DAT_OFFSET 82#ifdef CONFIG_ONENAND_IPL 83 orr r1, r1, #(1 << 1) @ 1 * 1-bit 84#else 85 bic r1, r1, #(1 << 1) 86#endif 87 str r1, [r0, #0x4] @ GPIO_DAT_OFFSET 88 89 /* Don't setup at s5pc100 */ 90 beq 100f 91 92 /* 93 * Initialize Async Register Setting for EVT1 94 * Because we are setting EVT1 as the default value of EVT0, 95 * setting EVT0 as well does not make things worse. 96 * Thus, for the simplicity, we set for EVT0, too 97 * 98 * The "Async Registers" are: 99 * 0xE0F0_0000 100 * 0xE1F0_0000 101 * 0xF180_0000 102 * 0xF190_0000 103 * 0xF1A0_0000 104 * 0xF1B0_0000 105 * 0xF1C0_0000 106 * 0xF1D0_0000 107 * 0xF1E0_0000 108 * 0xF1F0_0000 109 * 0xFAF0_0000 110 */ 111 ldr r0, =0xe0f00000 112 ldr r1, [r0] 113 bic r1, r1, #0x1 114 str r1, [r0] 115 116 ldr r0, =0xe1f00000 117 ldr r1, [r0] 118 bic r1, r1, #0x1 119 str r1, [r0] 120 121 ldr r0, =0xf1800000 122 ldr r1, [r0] 123 bic r1, r1, #0x1 124 str r1, [r0] 125 126 ldr r0, =0xf1900000 127 ldr r1, [r0] 128 bic r1, r1, #0x1 129 str r1, [r0] 130 131 ldr r0, =0xf1a00000 132 ldr r1, [r0] 133 bic r1, r1, #0x1 134 str r1, [r0] 135 136 ldr r0, =0xf1b00000 137 ldr r1, [r0] 138 bic r1, r1, #0x1 139 str r1, [r0] 140 141 ldr r0, =0xf1c00000 142 ldr r1, [r0] 143 bic r1, r1, #0x1 144 str r1, [r0] 145 146 ldr r0, =0xf1d00000 147 ldr r1, [r0] 148 bic r1, r1, #0x1 149 str r1, [r0] 150 151 ldr r0, =0xf1e00000 152 ldr r1, [r0] 153 bic r1, r1, #0x1 154 str r1, [r0] 155 156 ldr r0, =0xf1f00000 157 ldr r1, [r0] 158 bic r1, r1, #0x1 159 str r1, [r0] 160 161 ldr r0, =0xfaf00000 162 ldr r1, [r0] 163 bic r1, r1, #0x1 164 str r1, [r0] 165 166 /* 167 * Diable ABB block to reduce sleep current at low temperature 168 * Note that it's hidden register setup don't modify it 169 */ 170 ldr r0, =0xE010C300 171 ldr r1, =0x00800000 172 str r1, [r0] 173 174100: 175 /* IO retension release */ 176 ldreq r0, =S5PC100_OTHERS @ 0xE0108200 177 ldrne r0, =S5PC110_OTHERS @ 0xE010E000 178 ldr r1, [r0] 179 ldreq r2, =(1 << 31) @ IO_RET_REL 180 ldrne r2, =((1 << 31) | (1 << 30) | (1 << 29) | (1 << 28)) 181 orr r1, r1, r2 182 /* Do not release retention here for S5PC110 */ 183 streq r1, [r0] 184 185#ifndef CONFIG_ONENAND_IPL 186 /* Disable Watchdog */ 187 ldreq r0, =S5PC100_WATCHDOG_BASE @ 0xEA200000 188 ldrne r0, =S5PC110_WATCHDOG_BASE @ 0xE2700000 189 str r5, [r0] 190 191 /* setting SRAM */ 192 ldreq r0, =S5PC100_SROMC_BASE 193 ldrne r0, =S5PC110_SROMC_BASE 194 ldr r1, =0x9 195 str r1, [r0] 196#endif 197 198 /* S5PC100 has 3 groups of interrupt sources */ 199 ldreq r0, =S5PC100_VIC0_BASE @ 0xE4000000 200 ldrne r0, =S5PC110_VIC0_BASE @ 0xF2000000 201 add r1, r0, #0x00100000 202 add r2, r0, #0x00200000 203 204 /* Disable all interrupts (VIC0, VIC1 and VIC2) */ 205 mvn r3, #0x0 206 str r3, [r0, #0x14] @ INTENCLEAR 207 str r3, [r1, #0x14] @ INTENCLEAR 208 str r3, [r2, #0x14] @ INTENCLEAR 209 210#ifndef CONFIG_ONENAND_IPL 211 /* Set all interrupts as IRQ */ 212 str r5, [r0, #0xc] @ INTSELECT 213 str r5, [r1, #0xc] @ INTSELECT 214 str r5, [r2, #0xc] @ INTSELECT 215 216 /* Pending Interrupt Clear */ 217 str r5, [r0, #0xf00] @ INTADDRESS 218 str r5, [r1, #0xf00] @ INTADDRESS 219 str r5, [r2, #0xf00] @ INTADDRESS 220#endif 221 222#ifndef CONFIG_ONENAND_IPL 223 /* for UART */ 224 bl uart_asm_init 225 226 bl internal_ram_init 227#endif 228 229#ifdef CONFIG_ONENAND_IPL 230 /* init system clock */ 231 bl system_clock_init 232 233 /* OneNAND Sync Read Support at S5PC110 only 234 * RM[15] : Sync Read 235 * BRWL[14:12] : 7 CLK 236 * BL[11:9] : Continuous 237 * VHF[3] : Very High Frequency Enable (Over 83MHz) 238 * HF[2] : High Frequency Enable (Over 66MHz) 239 * WM[1] : Sync Write 240 */ 241 cmp r7, r8 242 ldrne r1, =0xE006 243 ldrne r0, =0xB001E442 244 strneh r1, [r0] 245 246 /* 247 * GCE[26] : Gated Clock Enable 248 * RPE[17] : Enables Read Prefetch 249 */ 250 ldrne r1, =((1 << 26) | (1 << 17) | 0xE006) 251 ldrne r0, =0xB0600000 252 strne r1, [r0, #0x100] @ ONENAND_IF_CTRL 253 ldrne r1, =0x1212 254 strne r1, [r0, #0x108] 255 256 /* Board detection to set proper memory configuration */ 257 cmp r7, r8 258 moveq r9, #1 /* r9 has 1Gib default at s5pc100 */ 259 movne r9, #2 /* r9 has 2Gib default at s5pc110 */ 260 261 ldr r2, =0xE0200200 262 ldr r4, [r2, #0x48] 263 264 bic r1, r4, #(0x3F << 4) /* PULLUP_DISABLE: 3 * 2-bit */ 265 bic r1, r1, #(0x3 << 2) /* PULLUP_DISABLE: 2 * 2-bit */ 266 bic r1, r1, #(0x3 << 14) /* PULLUP_DISABLE: 2 * 2-bit */ 267 str r1, [r2, #0x48] 268 /* For write completion */ 269 nop 270 nop 271 272 ldr r3, [r2, #0x44] 273 and r1, r3, #(0x7 << 2) 274 mov r1, r1, lsr #2 275 cmp r1, #0x5 276 moveq r9, #3 277 cmp r1, #0x6 278 moveq r9, #1 279 cmp r1, #0x7 280 moveq r9, #2 281 and r0, r3, #(0x1 << 1) 282 mov r0, r0, lsr #1 283 orr r1, r1, r0, lsl #3 284 cmp r1, #0x8 285 moveq r9, #3 286 and r1, r3, #(0x7 << 2) 287 mov r1, r1, lsr #2 288 and r0, r3, #(0x1 << 7) 289 mov r0, r0, lsr #7 290 orr r1, r1, r0, lsl #3 291 cmp r1, #0x9 292 moveq r9, #3 293 str r4, [r2, #0x48] /* Restore PULLUP configuration */ 294 295 bl mem_ctrl_asm_init 296 297 /* Wakeup support. Don't know if it's going to be used, untested. */ 298 ldreq r0, =S5PC100_RST_STAT 299 ldrne r0, =S5PC110_RST_STAT 300 ldr r1, [r0] 301 biceq r1, r1, #0xfffffff7 302 moveq r2, #(1 << 3) 303 bicne r1, r1, #0xfffeffff 304 movne r2, #(1 << 16) 305 cmp r1, r2 306 bne 1f 307wakeup: 308 /* turn off L2 cache */ 309 bl l2_cache_disable 310 311 cmp r7, r8 312 ldreq r0, =0xC100 313 ldrne r0, =0xC110 314 315 /* invalidate L2 cache also */ 316 bl invalidate_dcache 317 318 /* turn on L2 cache */ 319 bl l2_cache_enable 320 321 cmp r7, r8 322 /* Load return address and jump to kernel */ 323 ldreq r0, =S5PC100_INFORM0 324 ldrne r0, =S5PC110_INFORM0 325 326 /* r1 = physical address of s5pc1xx_cpu_resume function */ 327 ldr r1, [r0] 328 329 /* Jump to kernel (sleep-s5pc1xx.S) */ 330 mov pc, r1 331 nop 332 nop 333#else 334 cmp r7, r8 335 /* Clear wakeup status register */ 336 ldreq r0, =S5PC100_WAKEUP_STAT 337 ldrne r0, =S5PC110_WAKEUP_STAT 338 ldr r1, [r0] 339 str r1, [r0] 340 341 /* IO retension release */ 342 ldreq r0, =S5PC100_OTHERS @ 0xE0108200 343 ldrne r0, =S5PC110_OTHERS @ 0xE010E000 344 ldr r1, [r0] 345 ldreq r2, =(1 << 31) @ IO_RET_REL 346 ldrne r2, =((1 << 31) | (1 << 30) | (1 << 29) | (1 << 28)) 347 orr r1, r1, r2 348 str r1, [r0] 349 350#endif 351 b 1f 352 353didle_wakeup: 354 /* Wait when APLL is locked */ 355 ldr r0, =0xE0100100 @ S5PC110_APLL_CON 356lockloop: 357 ldr r1, [r0] 358 and r1, r1, #(1 << 29) 359 cmp r1, #(1 << 29) 360 bne lockloop 361 362 ldr r0, =S5PC110_INFORM0 363 ldr r1, [r0] 364 mov pc, r1 365 nop 366 nop 367 nop 368 nop 369 nop 370 3711: 372 mov lr, r11 373 mov pc, lr 374 375/* 376 * system_clock_init: Initialize core clock and bus clock. 377 * void system_clock_init(void) 378 */ 379system_clock_init: 380 ldr r0, =S5PC110_CLOCK_BASE @ 0xE0100000 381 382 /* Check S5PC100 */ 383 cmp r7, r8 384 bne 110f 385100: 386 /* Set Lock Time */ 387 ldr r1, =0xe10 @ Locktime : 0xe10 = 3600 388 str r1, [r0, #0x000] @ S5PC100_APLL_LOCK 389 str r1, [r0, #0x004] @ S5PC100_MPLL_LOCK 390 str r1, [r0, #0x008] @ S5PC100_EPLL_LOCK 391 str r1, [r0, #0x00C] @ S5PC100_HPLL_LOCK 392 393 /* S5P_APLL_CON */ 394 ldr r1, =0x81bc0400 @ SDIV 0, PDIV 4, MDIV 444 (1333MHz) 395 str r1, [r0, #0x100] 396 /* S5P_MPLL_CON */ 397 ldr r1, =0x80590201 @ SDIV 1, PDIV 2, MDIV 89 (267MHz) 398 str r1, [r0, #0x104] 399 /* S5P_EPLL_CON */ 400 ldr r1, =0x80870303 @ SDIV 3, PDIV 3, MDIV 135 (67.5MHz) 401 str r1, [r0, #0x108] 402 /* S5P_HPLL_CON */ 403 ldr r1, =0x80600603 @ SDIV 3, PDIV 6, MDIV 96 404 str r1, [r0, #0x10C] 405 406 ldr r1, [r0, #0x300] 407 ldr r2, =0x00003fff 408 bic r1, r1, r2 409 ldr r2, =0x00011301 410 411 orr r1, r1, r2 412 str r1, [r0, #0x300] 413 ldr r1, [r0, #0x304] 414 ldr r2, =0x00011110 415 orr r1, r1, r2 416 str r1, [r0, #0x304] 417 ldr r1, =0x00000001 418 str r1, [r0, #0x308] 419 420 /* Set Source Clock */ 421 ldr r1, =0x00001111 @ A, M, E, HPLL Muxing 422 str r1, [r0, #0x200] @ S5PC1XX_CLK_SRC0 423 424 b 200f 425110: 426 ldr r0, =0xE010C000 @ S5PC110_PWR_CFG 427 428 /* Set OSC_FREQ value */ 429 ldr r1, =0xf 430 str r1, [r0, #0x100] @ S5PC110_OSC_FREQ 431 432 /* Set MTC_STABLE value */ 433 ldr r1, =0xffffffff 434 str r1, [r0, #0x110] @ S5PC110_MTC_STABLE 435 436 /* Set CLAMP_STABLE value */ 437 ldr r1, =0x3ff03ff 438 str r1, [r0, #0x114] @ S5PC110_CLAMP_STABLE 439 440 ldr r0, =S5PC110_CLOCK_BASE @ 0xE0100000 441 442 /* Set Clock divider */ 443 ldr r1, =0x14131330 @ 1:1:4:4, 1:4:5 444 str r1, [r0, #0x300] 445 ldr r1, =0x11110111 @ UART[3210]: MMC[3210] 446 str r1, [r0, #0x310] 447 448 /* Set Lock Time */ 449 ldr r1, =0x2cf @ Locktime : 30us 450 str r1, [r0, #0x000] @ S5PC110_APLL_LOCK 451 ldr r1, =0xe10 @ Locktime : 0xe10 = 3600 452 str r1, [r0, #0x008] @ S5PC110_MPLL_LOCK 453 str r1, [r0, #0x010] @ S5PC110_EPLL_LOCK 454 str r1, [r0, #0x020] @ S5PC110_VPLL_LOCK 455 456 /* S5PC110_APLL_CON */ 457 ldr r1, =0x80C80601 @ 800MHz 458 str r1, [r0, #0x100] 459 /* S5PC110_MPLL_CON */ 460 ldr r1, =0x829B0C01 @ 667MHz 461 str r1, [r0, #0x108] 462 /* S5PC110_EPLL_CON */ 463 ldr r1, =0x80600602 @ 96MHz VSEL 0 P 6 M 96 S 2 464 str r1, [r0, #0x110] 465 /* S5PC110_VPLL_CON */ 466 ldr r1, =0x806C0603 @ 54MHz 467 str r1, [r0, #0x120] 468 469 /* Set Source Clock */ 470 ldr r1, =0x10001111 @ A, M, E, VPLL Muxing 471 str r1, [r0, #0x200] @ S5PC1XX_CLK_SRC0 472 473 /* OneDRAM(DMC0) clock setting */ 474 ldr r1, =0x01000000 @ ONEDRAM_SEL[25:24] 1 SCLKMPLL 475 str r1, [r0, #0x218] @ S5PC110_CLK_SRC6 476 ldr r1, =0x30000000 @ ONEDRAM_RATIO[31:28] 3 + 1 477 str r1, [r0, #0x318] @ S5PC110_CLK_DIV6 478 479 /* XCLKOUT = XUSBXTI 24MHz */ 480 add r2, r0, #0xE000 @ S5PC110_OTHERS 481 ldr r1, [r2] 482 orr r1, r1, #(0x3 << 8) @ CLKOUT[9:8] 3 XUSBXTI 483 str r1, [r2] 484 485 /* CLK_IP0 */ 486 ldr r1, =0x8fefeeb @ DMC[1:0] PDMA0[3] IMEM[5] 487 str r1, [r0, #0x460] @ S5PC110_CLK_IP0 488 489 /* CLK_IP1 */ 490 ldr r1, =0xe9fdf0f9 @ FIMD[0] USBOTG[16] 491 @ NANDXL[24] 492 str r1, [r0, #0x464] @ S5PC110_CLK_IP1 493 494 /* CLK_IP2 */ 495 ldr r1, =0xf75f7fc @ CORESIGHT[8] MODEM[9] 496 @ HOSTIF[10] HSMMC0[16] 497 @ HSMMC2[18] VIC[27:24] 498 str r1, [r0, #0x468] @ S5PC110_CLK_IP2 499 500 /* CLK_IP3 */ 501 ldr r1, =0x8eff038c @ I2C[8:6] 502 @ SYSTIMER[16] UART0[17] 503 @ UART1[18] UART2[19] 504 @ UART3[20] WDT[22] 505 @ PWM[23] GPIO[26] SYSCON[27] 506 str r1, [r0, #0x46c] @ S5PC110_CLK_IP3 507 508 /* CLK_IP4 */ 509 ldr r1, =0xfffffff1 @ CHIP_ID[0] TZPC[8:5] 510 str r1, [r0, #0x470] @ S5PC110_CLK_IP3 511 512200: 513 /* wait at least 200us to stablize all clock */ 514 mov r2, #0x10000 5151: subs r2, r2, #1 516 bne 1b 517 518 mov pc, lr 519 520#ifndef CONFIG_ONENAND_IPL 521internal_ram_init: 522 ldreq r0, =0xE3800000 523 ldrne r0, =0xF1500000 524 ldr r1, =0x0 525 str r1, [r0] 526 527 mov pc, lr 528#endif 529 530#ifndef CONFIG_ONENAND_IPL 531/* 532 * uart_asm_init: Initialize UART's pins 533 */ 534uart_asm_init: 535 /* set GPIO to enable UART0-UART4 */ 536 mov r0, r8 537 ldr r1, =0x22222222 538 str r1, [r0, #0x0] @ S5PC100_GPIO_A0_OFFSET 539 ldr r1, =0x00002222 540 str r1, [r0, #0x20] @ S5PC100_GPIO_A1_OFFSET 541 542 /* Check S5PC100 */ 543 cmp r7, r8 544 bne 110f 545 546 /* UART_SEL GPK0[5] at S5PC100 */ 547 add r0, r8, #0x2A0 @ S5PC100_GPIO_K0_OFFSET 548 ldr r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET 549 bic r1, r1, #(0xf << 20) @ 20 = 5 * 4-bit 550 orr r1, r1, #(0x1 << 20) @ Output 551 str r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET 552 553 ldr r1, [r0, #0x8] @ S5PC1XX_GPIO_PULL_OFFSET 554 bic r1, r1, #(0x3 << 10) @ 10 = 5 * 2-bit 555 orr r1, r1, #(0x2 << 10) @ Pull-up enabled 556 str r1, [r0, #0x8] @ S5PC1XX_GPIO_PULL_OFFSET 557 558 ldr r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET 559 orr r1, r1, #(1 << 5) @ 5 = 5 * 1-bit 560 str r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET 561 562 b 200f 563110: 564 /* 565 * Note that the following address 566 * 0xE020'0360 is reserved address at S5PC100 567 */ 568 /* UART_SEL MP0_5[7] at S5PC110 */ 569 add r0, r8, #0x360 @ S5PC110_GPIO_MP0_5_OFFSET 570 ldr r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET 571 bic r1, r1, #(0xf << 28) @ 28 = 7 * 4-bit 572 orr r1, r1, #(0x1 << 28) @ Output 573 str r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET 574 575 ldr r1, [r0, #0x8] @ S5PC1XX_GPIO_PULL_OFFSET 576 bic r1, r1, #(0x3 << 14) @ 14 = 7 * 2-bit 577 orr r1, r1, #(0x2 << 14) @ Pull-up enabled 578 str r1, [r0, #0x8] @ S5PC1XX_GPIO_PULL_OFFSET 579 580 ldr r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET 581 orr r1, r1, #(1 << 7) @ 7 = 7 * 1-bit 582 str r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET 583200: 584 mov pc, lr 585#endif 586