1/******************************************************************************* 2Copyright (C) Marvell International Ltd. and its affiliates 3 4This software file (the "File") is owned and distributed by Marvell 5International Ltd. and/or its affiliates ("Marvell") under the following 6alternative licensing terms. Once you have made an election to distribute the 7File under one of the following license alternatives, please (i) delete this 8introductory statement regarding license alternatives, (ii) delete the two 9license alternatives that you have not elected to use and (iii) preserve the 10Marvell copyright notice above. 11 12******************************************************************************** 13Marvell Commercial License Option 14 15If you received this File from Marvell and you have entered into a commercial 16license agreement (a "Commercial License") with Marvell, the File is licensed 17to you under the terms of the applicable Commercial License. 18 19******************************************************************************** 20Marvell GPL License Option 21 22If you received this File from Marvell, you may opt to use, redistribute and/or 23modify this File in accordance with the terms and conditions of the General 24Public License Version 2, June 1991 (the "GPL License"), a copy of which is 25available along with the File in the license.txt file or by writing to the Free 26Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or 27on the worldwide web at http://www.gnu.org/licenses/gpl.txt. 28 29THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED 30WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY 31DISCLAIMED. The GPL License provides additional details about this warranty 32disclaimer. 33******************************************************************************** 34Marvell BSD License Option 35 36If you received this File from Marvell, you may opt to use, redistribute and/or 37modify this File under the following licensing terms. 38Redistribution and use in source and binary forms, with or without modification, 39are permitted provided that the following conditions are met: 40 41 * Redistributions of source code must retain the above copyright notice, 42 this list of conditions and the following disclaimer. 43 44 * Redistributions in binary form must reproduce the above copyright 45 notice, this list of conditions and the following disclaimer in the 46 documentation and/or other materials provided with the distribution. 47 48 * Neither the name of Marvell nor the names of its contributors may be 49 used to endorse or promote products derived from this software without 50 specific prior written permission. 51 52THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 53ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 54WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 55DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 56ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 57(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 58LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 59ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 61SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 63*******************************************************************************/ 64 65/******************************************************************************* 66* mvDramIfBasicAsm.s 67* 68* DESCRIPTION: 69* Memory full detection and best timing configuration is done in 70* C code. C runtime environment requires a stack. This module API 71* initialize DRAM interface chip select 0 for basic functionality for 72* the use of stack. 73* The module API assumes DRAM information is stored in I2C EEPROM reside 74* in a given I2C address MV_BOARD_DIMM0_I2C_ADDR. The I2C EEPROM 75* internal data structure is assumed to be orgenzied in common DRAM 76* vendor SPD structure. 77* NOTE: DFCDL values are assumed to be already initialized prior to 78* this module API activity. 79* 80* 81* DEPENDENCIES: 82* None. 83* 84*******************************************************************************/ 85 86/* includes */ 87#define _ASMLANGUAGE 88#define MV_ASMLANGUAGE 89#include "mvOsAsm.h" 90#include "mvSysHwConfig.h" 91#include "mvDramIfRegs.h" 92#include "mvDramIfConfig.h" 93#include "ctrlEnv/sys/mvCpuIfRegs.h" 94#include "pex/mvPexRegs.h" 95#include "ctrlEnv/mvCtrlEnvSpec.h" 96#include "mvCommon.h" 97 98/* defines */ 99 100/* locals */ 101.data 102.globl _mvDramIfConfig 103.text 104.globl _mvDramIfMemInit 105 106/******************************************************************************* 107* _mvDramIfConfig - Basic DRAM interface initialization. 108* 109* DESCRIPTION: 110* The function will initialize the following DRAM parameters using the 111* values prepared by mvDramIfDetect routine. Values are located 112* in predefined registers. 113* 114* INPUT: 115* None. 116* 117* OUTPUT: 118* None. 119* 120* RETURN: 121* None. 122* 123*******************************************************************************/ 124 125_mvDramIfConfig: 126 127 /* Save register on stack */ 128 cmp sp, #0 129 beq no_stack_s 130save_on_stack: 131 stmdb sp!, {r1, r2, r3, r4} 132no_stack_s: 133 134 /* Dunit FTDLL Configuration Register */ 135 /* 0) Write to SDRAM FTDLL coniguration register */ 136 ldr r4, = SDRAM_FTDLL_REG_DEFAULT_LEFT; 137 ldr r1, =(INTER_REGS_BASE + SDRAM_FTDLL_CONFIG_LEFT_REG) 138 str r4, [r1] 139 ldr r4, = SDRAM_FTDLL_REG_DEFAULT_RIGHT; 140 ldr r1, =(INTER_REGS_BASE + SDRAM_FTDLL_CONFIG_RIGHT_REG) 141 str r4, [r1] 142 ldr r4, = SDRAM_FTDLL_REG_DEFAULT_UP; 143 ldr r1, =(INTER_REGS_BASE + SDRAM_FTDLL_CONFIG_UP_REG) 144 str r4, [r1] 145 146 /* 1) Write to SDRAM coniguration register */ 147 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG1) 148 ldr r4, [r1] 149 ldr r1, =(INTER_REGS_BASE + SDRAM_CONFIG_REG) 150 str r4, [r1] 151 152 /* 2) Write Dunit control low register */ 153 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG3) 154 ldr r4, [r1] 155 ldr r1, =(INTER_REGS_BASE + SDRAM_DUNIT_CTRL_REG) 156 str r4, [r1] 157 158 /* 2) Write Dunit control high register */ 159 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG13) 160 ldr r4, [r1] 161 ldr r1, =(INTER_REGS_BASE + SDRAM_DUNIT_CTRL_HI_REG) 162 str r4, [r1] 163 164 /* 3) Write SDRAM address control register */ 165 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG4) 166 ldr r4, [r1] 167 ldr r1, =(INTER_REGS_BASE + SDRAM_ADDR_CTRL_REG) 168 str r4, [r1] 169#if defined(MV_STATIC_DRAM_ON_BOARD) 170 /* 4) Write SDRAM bank 0 size register */ 171 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG0) 172 ldr r4, [r1] 173 ldr r1, =(INTER_REGS_BASE + SDRAM_SIZE_REG(0,0)) 174 str r4, [r1] 175#endif 176 177 /* 5) Write SDRAM open pages control register */ 178 ldr r1, =(INTER_REGS_BASE + SDRAM_OPEN_PAGE_CTRL_REG) 179 ldr r4, =SDRAM_OPEN_PAGES_CTRL_REG_DV 180 str r4, [r1] 181 182 /* 6) Write SDRAM timing Low register */ 183 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG5) 184 ldr r4, [r1] 185 ldr r1, =(INTER_REGS_BASE + SDRAM_TIMING_CTRL_LOW_REG) 186 str r4, [r1] 187 188 /* 7) Write SDRAM timing High register */ 189 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG6) 190 ldr r4, [r1] 191 ldr r1, =(INTER_REGS_BASE + SDRAM_TIMING_CTRL_HIGH_REG) 192 str r4, [r1] 193 194 /* Config DDR2 On Die Termination (ODT) registers */ 195 /* Write SDRAM DDR2 ODT control low register */ 196 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG7) 197 ldr r4, [r1] 198 ldr r1, =(INTER_REGS_BASE + DDR2_SDRAM_ODT_CTRL_LOW_REG) 199 str r4, [r1] 200 201 /* Write SDRAM DDR2 ODT control high register */ 202 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG8) 203 ldr r4, [r1] 204 ldr r1, =(INTER_REGS_BASE + DDR2_SDRAM_ODT_CTRL_HIGH_REG) 205 str r4, [r1] 206 207 /* Write SDRAM DDR2 Dunit ODT control register */ 208 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG9) 209 ldr r4, [r1] 210 ldr r1, =(INTER_REGS_BASE + DDR2_DUNIT_ODT_CONTROL_REG) 211 str r4, [r1] 212 213 /* Write DDR2 SDRAM timing Low register */ 214 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG11) 215 ldr r4, [r1] 216 ldr r1, =(INTER_REGS_BASE + SDRAM_DDR2_TIMING_LO_REG) 217 str r4, [r1] 218 219 /* Write DDR2 SDRAM timing High register */ 220 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG12) 221 ldr r4, [r1] 222 ldr r1, =(INTER_REGS_BASE + SDRAM_DDR2_TIMING_HI_REG) 223 str r4, [r1] 224 225 /* 8) Write SDRAM mode register */ 226 /* The CPU must not attempt to change the SDRAM Mode register setting */ 227 /* prior to DRAM controller completion of the DRAM initialization */ 228 /* sequence. To guarantee this restriction, it is recommended that */ 229 /* the CPU sets the SDRAM Operation register to NOP command, performs */ 230 /* read polling until the register is back in Normal operation value, */ 231 /* and then sets SDRAM Mode register to its new value. */ 232 233 /* 8.1 write 'nop' to SDRAM operation */ 234 mov r4, #0x5 /* 'NOP' command */ 235 MV_REG_WRITE_ASM(r4, r1, SDRAM_OPERATION_REG) 236 237 /* 8.2 poll SDRAM operation. Make sure its back to normal operation */ 238_sdramOpPoll1: 239 ldr r4, [r1] 240 cmp r4, #0 /* '0' = Normal SDRAM Mode */ 241 bne _sdramOpPoll1 242 243 /* 8.3 Now its safe to write new value to SDRAM Mode register */ 244 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG2) 245 ldr r4, [r1] 246 ldr r1, =(INTER_REGS_BASE + SDRAM_MODE_REG) 247 str r4, [r1] 248 249 /* 8.4 Make the Dunit write the DRAM its new mode */ 250 mov r4, #0x3 /* Mode Register Set command */ 251 MV_REG_WRITE_ASM (r4, r1, SDRAM_OPERATION_REG) 252 253 /* 8.5 poll SDRAM operation. Make sure its back to normal operation */ 254_sdramOpPoll2: 255 ldr r4, [r1] 256 cmp r4, #0 /* '0' = Normal SDRAM Mode */ 257 bne _sdramOpPoll2 258 259 /* Now its safe to write new value to SDRAM Extended Mode regist */ 260 ldr r1, =(INTER_REGS_BASE + DRAM_BUF_REG10) 261 ldr r4, [r1] 262 ldr r1, =(INTER_REGS_BASE + SDRAM_EXTENDED_MODE_REG) 263 str r4, [r1] 264 265 /* 9) Write SDRAM Extended mode register This operation should be */ 266 /* done for each memory bank */ 267 /* write 'nop' to SDRAM operation */ 268 mov r4, #0x5 /* 'NOP' command */ 269 MV_REG_WRITE_ASM (r4, r1, SDRAM_OPERATION_REG) 270 271 /* poll SDRAM operation. Make sure its back to normal operation */ 272_sdramOpPoll3: 273 ldr r4, [r1] 274 cmp r4, #0 /* '0' = Normal SDRAM Mode */ 275 bne _sdramOpPoll3 276 /* Go over each of the Banks */ 277 ldr r3, =0 /* r3 = DRAM bank Num */ 278 279extModeLoop: 280 /* Set the SDRAM Operation Control to each of the DRAM banks */ 281 mov r4, r3 /* Do not swap the bank counter value */ 282 MV_REG_WRITE_ASM (r4, r1, SDRAM_OPERATION_CTRL_REG) 283 284 /* Make the Dunit write the DRAM its new mode */ 285 mov r4, #0x4 /* Extended Mode Register Set command */ 286 MV_REG_WRITE_ASM (r4, r1, SDRAM_OPERATION_REG) 287 288 /* poll SDRAM operation. Make sure its back to normal operation */ 289_sdramOpPoll4: 290 ldr r4, [r1] 291 cmp r4, #0 /* '0' = Normal SDRAM Mode */ 292 bne _sdramOpPoll4 293 294 add r3, r3, #1 295 cmp r3, #4 /* 4 = Number of banks */ 296 bne extModeLoop 297 298extModeEnd: 299cmp sp, #0 300 beq no_stack_l 301 mov r1, LR /* Save link register */ 302#if defined(MV78XX0) 303 bl _mvDramIfMemInit 304#endif 305 mov LR,r1 /* restore link register */ 306load_from_stack: 307 /* Restore registers */ 308 ldmia sp!, {r1, r2, r3, r4} 309no_stack_l: 310 311 mov pc, lr 312 313 314/******************************************************************************* 315* _mvDramIfEccMemInit - Basic DRAM ECC initialization. 316* 317* DESCRIPTION: 318* 319* INPUT: 320* None. 321* 322* OUTPUT: 323* None. 324* 325* RETURN: 326* None. 327* 328*******************************************************************************/ 329#define XOR_CHAN0 0 /* XOR channel 0 used for memory initialization */ 330#define XOR_UNIT0 0 /* XOR unit 0 used for memory initialization */ 331#define XOR_ADDR_DEC_WIN0 0 /* Enable DRAM access using XOR decode window 0 */ 332/* XOR engine register offsets macros */ 333#define XOR_CONFIG_REG(chan) (XOR_UNIT_BASE(0) + 0x10 + ((chan) * 4)) 334#define XOR_ACTIVATION_REG(chan) (XOR_UNIT_BASE(0) + 0x20 + ((chan) * 4)) 335#define XOR_CAUSE_REG (XOR_UNIT_BASE(0) + 0x30) 336#define XOR_ERROR_CAUSE_REG (XOR_UNIT_BASE(0) + 0x50) 337#define XOR_ERROR_ADDR_REG (XOR_UNIT_BASE(0) + 0x60) 338#define XOR_INIT_VAL_LOW_REG (XOR_UNIT_BASE(0) + 0x2E0) 339#define XOR_INIT_VAL_HIGH_REG (XOR_UNIT_BASE(0) + 0x2E4) 340#define XOR_DST_PTR_REG(chan) (XOR_UNIT_BASE(0) + 0x2B0 + ((chan) * 4)) 341#define XOR_BLOCK_SIZE_REG(chan) (XOR_UNIT_BASE(0) + 0x2C0 + ((chan) * 4)) 342 343/* XOR Engine Address Decoding Register Map */ 344#define XOR_WINDOW_CTRL_REG(unit,chan) (XOR_UNIT_BASE(unit)+(0x240 + ((chan) * 4))) 345#define XOR_BASE_ADDR_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x250 + ((winNum) * 4))) 346#define XOR_SIZE_MASK_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x270 + ((winNum) * 4))) 347 348.globl _mvDramIfEccMemInit 349/******************************************************************************* 350* _mvDramIfEccMemInit - mem init for dram cs 351* 352* DESCRIPTION: 353* This function will clean the cs by ussing the XOR mem init. 354* 355* INPUT: 356* r0 - dram bank number. 357* 358* OUTPUT: 359* none 360*/ 361_mvDramIfEccMemInit: 362 363 /* Save register on stack */ 364 cmp sp, #0 365 beq no_stack_s1 366save_on_stack1: 367 stmdb sp!, {r0,r1, r2, r3, r4, r5, r6} 368no_stack_s1: 369 370 ldr r1, = 0 371 372 /* Disable all XOR address decode windows to avoid possible overlap */ 373 MV_REG_WRITE_ASM (r1, r5, (XOR_WINDOW_CTRL_REG(XOR_UNIT0,XOR_CHAN0))) 374 375 /* Init r5 to first XOR_SIZE_MASK_REG */ 376 mov r5, r0, LSL #3 377 add r5, r5,#0x1500 378 add r5, r5,#0x04 379 add r5, r5,#(INTER_REGS_BASE) 380 ldr r6, [r5] 381 HTOLL(r6,r5) 382 MV_REG_WRITE_ASM (r6, r5, XOR_SIZE_MASK_REG(XOR_UNIT0,XOR_ADDR_DEC_WIN0)) 383 384 mov r5, r0, LSL #3 385 add r5, r5,#0x1500 386 add r5, r5,#(INTER_REGS_BASE) 387 ldr r6, [r5] 388 /* Update destination & size */ 389 MV_REG_WRITE_ASM(r6, r5, XOR_DST_PTR_REG(XOR_CHAN0)) 390 HTOLL(r6,r5) 391 /* Init r6 to first XOR_BASE_ADDR_REG */ 392 ldr r4, = 0xf 393 ldr r5, = 0x1 394 mov r5, r5, LSL r0 395 bic r4, r4, r5 396 mov r4, r4, LSL #8 397 398 orr r6, r6, r4 399 MV_REG_WRITE_ASM (r6, r5, XOR_BASE_ADDR_REG(XOR_UNIT0,XOR_ADDR_DEC_WIN0)) 400 401 ldr r6, = 0xff0001 402 MV_REG_WRITE_ASM (r6, r5, XOR_WINDOW_CTRL_REG(XOR_UNIT0,XOR_CHAN0)) 403 404 /* Configure XOR engine for memory init function. */ 405 MV_REG_READ_ASM (r6, r5, XOR_CONFIG_REG(XOR_CHAN0)) 406 and r6, r6, #~0x7 /* Clear operation mode field */ 407 orr r6, r6, #0x4 /* Set operation to memory init */ 408 MV_REG_WRITE_ASM(r6, r5, XOR_CONFIG_REG(XOR_CHAN0)) 409 410 /* Set initVal in the XOR Engine Initial Value Registers */ 411 ldr r6, = 0xfeedfeed 412 MV_REG_WRITE_ASM(r6, r5, XOR_INIT_VAL_LOW_REG) 413 ldr r6, = 0xfeedfeed 414 MV_REG_WRITE_ASM(r6, r5, XOR_INIT_VAL_HIGH_REG) 415 416 /* Set block size using DRAM bank size */ 417 418 mov r5, r0, LSL #3 419 add r5, r5,#0x1500 420 add r5, r5,#0x04 421 add r5, r5,#(INTER_REGS_BASE) 422 423 ldr r6, [r5] 424 HTOLL(r6,r5) 425 and r6, r6, #SCSR_SIZE_MASK 426 mov r5, r6, LSR #SCSR_SIZE_OFFS 427 add r5, r5, #1 428 mov r6, r5, LSL #SCSR_SIZE_OFFS 429 MV_REG_WRITE_ASM(r6, r5, XOR_BLOCK_SIZE_REG(XOR_CHAN0)) 430 431 /* Clean interrupt cause*/ 432 MV_REG_WRITE_ASM(r1, r5, XOR_CAUSE_REG) 433 434 /* Clean error interrupt cause*/ 435 MV_REG_READ_ASM(r6, r5, XOR_ERROR_CAUSE_REG) 436 MV_REG_READ_ASM(r6, r5, XOR_ERROR_ADDR_REG) 437 438 /* Start transfer */ 439 MV_REG_READ_ASM (r6, r5, XOR_ACTIVATION_REG(XOR_CHAN0)) 440 orr r6, r6, #0x1 /* Preform start command */ 441 MV_REG_WRITE_ASM(r6, r5, XOR_ACTIVATION_REG(XOR_CHAN0)) 442 443 /* Wait for engine to finish */ 444waitForComplete: 445 MV_REG_READ_ASM(r6, r5, XOR_CAUSE_REG) 446 and r6, r6, #2 447 cmp r6, #0 448 beq waitForComplete 449 450 /* Clear all error report registers */ 451 MV_REG_WRITE_ASM(r1, r5, SDRAM_SINGLE_BIT_ERR_CNTR_REG) 452 MV_REG_WRITE_ASM(r1, r5, SDRAM_DOUBLE_BIT_ERR_CNTR_REG) 453 454 MV_REG_WRITE_ASM(r1, r5, SDRAM_ERROR_CAUSE_REG) 455 456 cmp sp, #0 457 beq no_stack_l1 458load_from_stack1: 459 ldmia sp!, {r0, r1, r2, r3, r4, r5, r6} 460no_stack_l1: 461 mov pc, lr 462 463 464/******************************************************************************* 465* mvDramIfMemInit - Use XOR to clear all memory. 466* 467* DESCRIPTION: 468* Use assembler function _mvDramIfEccMemInit to fill all memory with FEADFEAD pattern. 469* INPUT: 470* None. 471* 472* OUTPUT: 473* None. 474* 475* RETURN: 476* None. 477* 478*******************************************************************************/ 479#if defined(MV78XX0) 480 481_mvDramIfMemInit: 482 stmdb sp!, {r0,r1, r2, r3, r4, r5, r6} 483 mov r6, LR /* Save link register */ 484 /* Check if dram bank 0 has to be init for ECC */ 485 MV_REG_READ_ASM (r0, r5, SDRAM_SIZE_REG(0,0)) 486 and r3, r0, #SCSR_WIN_EN 487 cmp r3, #0 488 beq no_bank_0 489 MV_REG_READ_ASM(r0, r5, SDRAM_BASE_ADDR_REG(0,0)) 490 cmp r0, #0 491 beq no_bank_0 492 mov r0,#0 493 bl _mvDramIfEccMemInit 494 495no_bank_0: 496 /* Check if dram bank 1 has to be init for ECC */ 497 MV_REG_READ_ASM (r0, r5, SDRAM_SIZE_REG(0,1)) 498 and r0, r0, #SCSR_WIN_EN 499 cmp r0, #0 500 beq no_bank_1 501 mov r0,#1 502 bl _mvDramIfEccMemInit 503no_bank_1: 504 /* Check if dram bank 2 has to be init for ECC */ 505 MV_REG_READ_ASM (r0, r5, SDRAM_SIZE_REG(0,2)) 506 and r0, r0, #SCSR_WIN_EN 507 cmp r0, #0 508 beq no_bank_2 509 MV_REG_READ_ASM(r0, r5, SDRAM_BASE_ADDR_REG(0,2)) 510 cmp r0, #0 511 beq no_bank_2 512 mov r0,#2 513 bl _mvDramIfEccMemInit 514 515no_bank_2: 516 /* Check if dram bank 3 has to be init for ECC */ 517 MV_REG_READ_ASM (r0, r5, SDRAM_SIZE_REG(0,3)) 518 and r0, r0, #SCSR_WIN_EN 519 cmp r0, #0 520 beq no_bank_3 521 mov r0,#3 522 bl _mvDramIfEccMemInit 523no_bank_3: 524 mov LR ,r6 /* restore link register */ 525 ldmia sp!, {r0, r1, r2, r3, r4, r5, r6} 526 mov pc, lr 527#endif 528 529