📄 sdram_init.c
字号:
DP (printf ("setting up sdram address control (0x1410) with: %08lx \n", tmp));/* ------------------------------------------------------------------------------ *//* same settings for registerd & non-registerd DDR SDRAM */ DP (printf ("setting up sdram_timing_control_low (0x1408) with: %08x \n", 0x01501220)); /*ronen db64460 */ GT_REG_WRITE (SDRAM_TIMING_CONTROL_LOW, 0x01501220);/* ------------------------------------------------------------------------------ */ /* SDRAM configuration */ tmp = GTREGREAD (SDRAM_CONFIG); if (info->registeredAddrAndControlInputs || info->registeredDQMBinputs) { tmp |= (1 << 17); DP (printf ("SPD says: registered Addr. and Cont.: %d; registered DQMBinputs: %d\n", info->registeredAddrAndControlInputs, info->registeredDQMBinputs)); } /* Use buffer 1 to return read data to the CPU * Page 426 MV6indent: Standard input:1464: Warning:old style assignment ambiguity in "=*". Assuming "= *"indent: Standard input:1465: Warning:old style assignment ambiguity in "=*". Assuming "= *"4460 */ tmp |= (1 << 26); DP (printf ("Before Buffer assignment - sdram_conf (0x1400): %08x\n", GTREGREAD (SDRAM_CONFIG))); DP (printf ("After Buffer assignment - sdram_conf (0x1400): %08x\n", GTREGREAD (SDRAM_CONFIG))); /* SDRAM timing To_do: *//* ------------------------------------------------------------------------------ */ /* ronen db64460 */ DP (printf ("setting up sdram_timing_control_high (0x140c) with: %08x \n", 0xc)); GT_REG_WRITE (SDRAM_TIMING_CONTROL_HIGH, 0xc); DP (printf ("setting up sdram address pads control (0x14c0) with: %08x \n", 0x7d5014a)); GT_REG_WRITE (SDRAM_ADDR_CTRL_PADS_CALIBRATION, 0x7d5014a); DP (printf ("setting up sdram data pads control (0x14c4) with: %08x \n", 0x7d5014a)); GT_REG_WRITE (SDRAM_DATA_PADS_CALIBRATION, 0x7d5014a);/* ------------------------------------------------------------------------------ */ /* set the SDRAM configuration for each bank *//* for (i = info->slot * 2; i < ((info->slot * 2) + info->banks); i++) */ { i = info->slot; DP (printf ("\n*** Running a MRS cycle for bank %d ***\n", i)); /* map the bank */ memory_map_bank (i, 0, GB / 4); /* set SDRAM mode */ /* To_do check it */ GT_REG_WRITE (SDRAM_OPERATION, 0x3); check = GTREGREAD (SDRAM_OPERATION); DP (printf ("\n*** SDRAM_OPERATION 1418 (0 = Normal Operation) = %08lx ***\n", check)); /* switch back to normal operation mode */ GT_REG_WRITE (SDRAM_OPERATION, 0); check = GTREGREAD (SDRAM_OPERATION); DP (printf ("\n*** SDRAM_OPERATION 1418 (0 = Normal Operation) = %08lx ***\n", check)); /* unmap the bank */ memory_map_bank (i, 0, 0); } return 0;}/* * Check memory range for valid RAM. A simple memory test determines * the actually available RAM size between addresses `base' and * `base + maxsize'. Some (not all) hardware errors are detected: * - short between address lines * - short between data lines */long int dram_size (long int *base, long int maxsize){ volatile long int *addr, *b = base; long int cnt, val, save1, save2;#define STARTVAL (1<<20) /* start test at 1M */ for (cnt = STARTVAL / sizeof (long); cnt < maxsize / sizeof (long); cnt <<= 1) { addr = base + cnt; /* pointer arith! */ save1 = *addr; /* save contents of addr */ save2 = *b; /* save contents of base */ *addr = cnt; /* write cnt to addr */ *b = 0; /* put null at base */ /* check at base address */ if ((*b) != 0) { *addr = save1; /* restore *addr */ *b = save2; /* restore *b */ return (0); } val = *addr; /* read *addr */ val = *addr; /* read *addr */ *addr = save1; *b = save2; if (val != cnt) { DP (printf ("Found %08x at Address %08x (failure)\n", (unsigned int) val, (unsigned int) addr)); /* fix boundary condition.. STARTVAL means zero */ if (cnt == STARTVAL / sizeof (long)) cnt = 0; return (cnt * sizeof (long)); } } return maxsize;}/* ------------------------------------------------------------------------- *//* ppcboot interface function to SDRAM init - this is where all the * controlling logic happens */long int initdram (int board_type){ int s0 = 0, s1 = 0; int checkbank[4] = {[0 ... 3] = 0 }; ulong realsize, total, check; AUX_MEM_DIMM_INFO dimmInfo1; AUX_MEM_DIMM_INFO dimmInfo2; int nhr, bank_no; ulong dest, memSpaceAttr; /* first, use the SPD to get info about the SDRAM/ DDRRAM */ /* check the NHR bit and skip mem init if it's already done */ nhr = get_hid0 () & (1 << 16); if (nhr) { printf ("Skipping SD- DDRRAM setup due to NHR bit being set\n"); } else { /* DIMM0 */ s0 = check_dimm (0, &dimmInfo1); /* DIMM1 */ s1 = check_dimm (1, &dimmInfo2); memory_map_bank (0, 0, 0); memory_map_bank (1, 0, 0); memory_map_bank (2, 0, 0); memory_map_bank (3, 0, 0); /* ronen check correct set of DIMMS */ if (dimmInfo1.numOfModuleBanks && dimmInfo2.numOfModuleBanks) { if (dimmInfo1.errorCheckType != dimmInfo2.errorCheckType) printf ("***WARNNING***!!!! different ECC support of the DIMMS\n"); if (dimmInfo1.maxClSupported_DDR != dimmInfo2.maxClSupported_DDR) printf ("***WARNNING***!!!! different CAL setting of the DIMMS\n"); if (dimmInfo1.registeredAddrAndControlInputs != dimmInfo2.registeredAddrAndControlInputs) printf ("***WARNNING***!!!! different Registration setting of the DIMMS\n"); } if (dimmInfo1.numOfModuleBanks && setup_sdram (&dimmInfo1)) { printf ("Setup for DIMM1 failed.\n"); } if (dimmInfo2.numOfModuleBanks && setup_sdram (&dimmInfo2)) { printf ("Setup for DIMM2 failed.\n"); } /* set the NHR bit */ set_hid0 (get_hid0 () | (1 << 16)); } /* next, size the SDRAM banks */ realsize = total = 0; check = GB / 4; if (dimmInfo1.numOfModuleBanks > 0) { checkbank[0] = 1; } if (dimmInfo1.numOfModuleBanks > 1) { checkbank[1] = 1; } if (dimmInfo1.numOfModuleBanks > 2) printf ("Error, SPD claims DIMM1 has >2 banks\n"); printf ("-- DIMM1 has %d banks\n", dimmInfo1.numOfModuleBanks); if (dimmInfo2.numOfModuleBanks > 0) { checkbank[2] = 1; } if (dimmInfo2.numOfModuleBanks > 1) { checkbank[3] = 1; } if (dimmInfo2.numOfModuleBanks > 2) printf ("Error, SPD claims DIMM2 has >2 banks\n"); printf ("-- DIMM2 has %d banks\n", dimmInfo2.numOfModuleBanks); for (bank_no = 0; bank_no < CFG_DRAM_BANKS; bank_no++) { /* skip over banks that are not populated */ if (!checkbank[bank_no]) continue; /* ronen - realsize = dram_size((long int *)total, check); */ if (bank_no == 0 || bank_no == 1) { if (checkbank[1] == 1) realsize = dimmInfo1.size / 2; else realsize = dimmInfo1.size; } if (bank_no == 2 || bank_no == 3) { if (checkbank[3] == 1) realsize = dimmInfo2.size / 2; else realsize = dimmInfo2.size; } memory_map_bank (bank_no, total, realsize); /* ronen - initialize the DRAM for ECC */#ifdef CONFIG_MV64460_ECC if ((dimmInfo1.errorCheckType != 0) && ((dimmInfo2.errorCheckType != 0) || (dimmInfo2.numOfModuleBanks == 0))) { printf ("ECC Initialization of Bank %d:", bank_no); memSpaceAttr = ((~(BIT0 << bank_no)) & 0xf) << 8; mvDmaSetMemorySpace (0, 0, memSpaceAttr, total, realsize); for (dest = total; dest < total + realsize; dest += _8M) { mvDmaTransfer (0, total, dest, _8M, BIT8 /*DMA_DTL_128BYTES */ | BIT3 /*DMA_HOLD_SOURCE_ADDR */ | BIT11 /*DMA_BLOCK_TRANSFER_MODE */ ); while (mvDmaIsChannelActive (0)); } printf (" PASS\n"); }#endif total += realsize; } /* ronen */ switch ((GTREGREAD (0x141c) >> 4) & 0x7) { case 0x2: printf ("CAS Latency = 2"); break; case 0x3: printf ("CAS Latency = 3"); break; case 0x5: printf ("CAS Latency = 1.5"); break; case 0x6: printf ("CAS Latency = 2.5"); break; } printf (" tRP = %d tRAS = %d tRCD=%d\n", ((GTREGREAD (0x1408) >> 8) & 0xf) + 1, ((GTREGREAD (0x1408) >> 20) & 0xf) + 1, ((GTREGREAD (0x1408) >> 4) & 0xf) + 1);/* Setup Ethernet DMA Adress window to DRAM Area */ if (total > _256M) printf ("*** ONLY the first 256MB DRAM memory are used out of the "); else printf ("Total SDRAM memory is "); /* (cause all the 4 BATS are taken) */ return (total);}/* ronen- add Idma functions for usage of the ecc dram init. *//******************************************************************************** mvDmaIsChannelActive - Checks if a engine is busy.********************************************************************************/int mvDmaIsChannelActive (int engine){ ulong data; data = GTREGREAD (MV64460_DMA_CHANNEL0_CONTROL + 4 * engine); if (data & BIT14 /*activity status */ ) { return 1; } return 0;}/******************************************************************************** mvDmaSetMemorySpace - Set a DMA memory window for the DMA's address decoding* map.*******************************************************************************/int mvDmaSetMemorySpace (ulong memSpace, ulong memSpaceTarget, ulong memSpaceAttr, ulong baseAddress, ulong size){ ulong temp; /* The base address must be aligned to the size. */ if (baseAddress % size != 0) { return 0; } if (size >= 0x10000 /*64K */ ) { size &= 0xffff0000; baseAddress = (baseAddress & 0xffff0000); /* Set the new attributes */ GT_REG_WRITE (MV64460_DMA_BASE_ADDR_REG0 + memSpace * 8, (baseAddress | memSpaceTarget | memSpaceAttr)); GT_REG_WRITE ((MV64460_DMA_SIZE_REG0 + memSpace * 8), (size - 1) & 0xffff0000); temp = GTREGREAD (MV64460_DMA_BASE_ADDR_ENABLE_REG); GT_REG_WRITE (DMA_BASE_ADDR_ENABLE_REG, (temp & ~(BIT0 << memSpace))); return 1; } return 0;}/******************************************************************************** mvDmaTransfer - Transfer data from sourceAddr to destAddr on one of the 4* DMA channels.********************************************************************************/int mvDmaTransfer (int engine, ulong sourceAddr, ulong destAddr, ulong numOfBytes, ulong command){ ulong engOffReg = 0; /* Engine Offset Register */ if (numOfBytes > 0xffff) { command = command | BIT31 /*DMA_16M_DESCRIPTOR_MODE */ ; } command = command | ((command >> 6) & 0x7); engOffReg = engine * 4; GT_REG_WRITE (MV64460_DMA_CHANNEL0_BYTE_COUNT + engOffReg, numOfBytes); GT_REG_WRITE (MV64460_DMA_CHANNEL0_SOURCE_ADDR + engOffReg, sourceAddr); GT_REG_WRITE (MV64460_DMA_CHANNEL0_DESTINATION_ADDR + engOffReg, destAddr); command = command | BIT12 /*DMA_CHANNEL_ENABLE */ | BIT9 /*DMA_NON_CHAIN_MODE */ ; /* Activate DMA engine By writting to mvDmaControlRegister */ GT_REG_WRITE (MV64460_DMA_CHANNEL0_CONTROL + engOffReg, command); return 1;}/**************************************************************************************** * SDRAM INIT * * This procedure detect all Sdram types: 64, 128, 256, 512 Mbit, 1Gbit and 2Gb * * This procedure fits only the Atlantis * * * ***************************************************************************************//**************************************************************************************** * DFCDL initialize MV643xx Design Considerations * * * ***************************************************************************************/int set_dfcdlInit (void){ /*ronen the dfcdl init are done by the I2C */ return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -