sdram_init.c

来自「适合KS8695X」· C语言 代码 · 共 1,974 行 · 第 1/5 页

C
1,974
字号
	case 32:		/* 2 Gbit */
		DP (printf ("RAM-Device_size 1Gbit or 2Gbit)\n"));
		tmp |= (0x02 << 4);
		break;
	default:
		printf ("Error in dram size calculation\n");
		printf ("RAM-Device_size is unsupported\n");
		hang ();
	}

	/* SDRAM address control */
	GT_REG_WRITE (SDRAM_ADDR_CONTROL, tmp);
	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					*
 *											*
 *****************************

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?