507 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			507 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * sys-dram.c
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com>
							 | 
						||
| 
								 | 
							
								 * Official site: http://xboot.org
							 | 
						||
| 
								 | 
							
								 * Mobile phone: +86-18665388956
							 | 
						||
| 
								 | 
							
								 * QQ: 8192542
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This program is free software; you can redistribute it and/or modify
							 | 
						||
| 
								 | 
							
								 * it under the terms of the GNU General Public License as published by
							 | 
						||
| 
								 | 
							
								 * the Free Software Foundation; either version 2 of the License, or
							 | 
						||
| 
								 | 
							
								 * (at your option) any later version.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This program is distributed in the hope that it will be useful,
							 | 
						||
| 
								 | 
							
								 * but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						||
| 
								 | 
							
								 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
							 | 
						||
| 
								 | 
							
								 * GNU General Public License for more details.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * You should have received a copy of the GNU General Public License
							 | 
						||
| 
								 | 
							
								 * along with this program; if not, write to the Free Software Foundation,
							 | 
						||
| 
								 | 
							
								 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#include <stdint.h>
							 | 
						||
| 
								 | 
							
								#include <f1c100s/reg-ccu.h>
							 | 
						||
| 
								 | 
							
								#include <f1c100s/reg-dram.h>
							 | 
						||
| 
								 | 
							
								#include <io.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define PLL_DDR_CLK			(156000000)
							 | 
						||
| 
								 | 
							
								#define SDR_T_CAS			(0x2)
							 | 
						||
| 
								 | 
							
								#define SDR_T_RAS			(0x8)
							 | 
						||
| 
								 | 
							
								#define SDR_T_RCD			(0x3)
							 | 
						||
| 
								 | 
							
								#define SDR_T_RP			(0x3)
							 | 
						||
| 
								 | 
							
								#define SDR_T_WR			(0x3)
							 | 
						||
| 
								 | 
							
								#define SDR_T_RFC			(0xd)
							 | 
						||
| 
								 | 
							
								#define SDR_T_XSR			(0xf9)
							 | 
						||
| 
								 | 
							
								#define SDR_T_RC			(0xb)
							 | 
						||
| 
								 | 
							
								#define SDR_T_INIT			(0x8)
							 | 
						||
| 
								 | 
							
								#define SDR_T_INIT_REF		(0x7)
							 | 
						||
| 
								 | 
							
								#define SDR_T_WTR			(0x2)
							 | 
						||
| 
								 | 
							
								#define SDR_T_RRD			(0x2)
							 | 
						||
| 
								 | 
							
								#define SDR_T_XP			(0x0)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								enum dram_type_t
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DRAM_TYPE_SDR	= 0,
							 | 
						||
| 
								 | 
							
									DRAM_TYPE_DDR	= 1,
							 | 
						||
| 
								 | 
							
									DRAM_TYPE_MDDR	= 2,
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dram_para_t
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									uint32_t base;				/* dram base address */
							 | 
						||
| 
								 | 
							
									uint32_t size;				/* dram size (unit: MByte) */
							 | 
						||
| 
								 | 
							
									uint32_t clk;				/* dram work clock (unit: MHz) */
							 | 
						||
| 
								 | 
							
									uint32_t access_mode;		/* 0: interleave mode 1: sequence mode */
							 | 
						||
| 
								 | 
							
									uint32_t cs_num;			/* dram chip count  1: one chip  2: two chip */
							 | 
						||
| 
								 | 
							
									uint32_t ddr8_remap;		/* for 8bits data width DDR 0: normal  1: 8bits */
							 | 
						||
| 
								 | 
							
									enum dram_type_t sdr_ddr;
							 | 
						||
| 
								 | 
							
									uint32_t bwidth;			/* dram bus width */
							 | 
						||
| 
								 | 
							
									uint32_t col_width;		/* column address width */
							 | 
						||
| 
								 | 
							
									uint32_t row_width;		/* row address width */
							 | 
						||
| 
								 | 
							
									uint32_t bank_size;		/* dram bank count */
							 | 
						||
| 
								 | 
							
									uint32_t cas;				/* dram cas */
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline void sdelay(int loops)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									__asm__ __volatile__ ("1:\n" "subs %0, %1, #1\n"
							 | 
						||
| 
								 | 
							
										"bne 1b":"=r" (loops):"0"(loops));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void dram_delay(int ms)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									sdelay(ms * 2 * 1000);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int dram_initial(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									unsigned int time = 0xffffff;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									write32(F1C100S_DRAM_BASE + DRAM_SCTLR, read32(F1C100S_DRAM_BASE + DRAM_SCTLR) | 0x1);
							 | 
						||
| 
								 | 
							
									while((read32(F1C100S_DRAM_BASE + DRAM_SCTLR) & 0x1) && time--)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(time == 0)
							 | 
						||
| 
								 | 
							
											return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int dram_delay_scan(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									unsigned int time = 0xffffff;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									write32(F1C100S_DRAM_BASE + DRAM_DDLYR, read32(F1C100S_DRAM_BASE + DRAM_DDLYR) | 0x1);
							 | 
						||
| 
								 | 
							
									while((read32(F1C100S_DRAM_BASE + DRAM_DDLYR) & 0x1) && time--)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(time == 0)
							 | 
						||
| 
								 | 
							
											return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void dram_set_autofresh_cycle(uint32_t clk)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									uint32_t val = 0;
							 | 
						||
| 
								 | 
							
									uint32_t row = 0;
							 | 
						||
| 
								 | 
							
									uint32_t temp = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									row = read32(F1C100S_DRAM_BASE + DRAM_SCONR);
							 | 
						||
| 
								 | 
							
									row &= 0x1e0;
							 | 
						||
| 
								 | 
							
									row >>= 0x5;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(row == 0xc)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(clk >= 1000000)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											temp = clk + (clk >> 3) + (clk >> 4) + (clk >> 5);
							 | 
						||
| 
								 | 
							
											while(temp >= (10000000 >> 6))
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												temp -= (10000000 >> 6);
							 | 
						||
| 
								 | 
							
												val++;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											val = (clk * 499) >> 6;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if(row == 0xb)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(clk >= 1000000)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											temp = clk + (clk >> 3) + (clk >> 4) + (clk >> 5);
							 | 
						||
| 
								 | 
							
											while(temp >= (10000000 >> 7))
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												temp -= (10000000 >> 7);
							 | 
						||
| 
								 | 
							
												val++;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											val = (clk * 499) >> 5;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									write32(F1C100S_DRAM_BASE + DRAM_SREFR, val);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int dram_para_setup(struct dram_para_t * para)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									uint32_t val = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    val = (para->ddr8_remap) |
							 | 
						||
| 
								 | 
							
								    	(0x1 << 1) |
							 | 
						||
| 
								 | 
							
										((para->bank_size >> 2) << 3) |
							 | 
						||
| 
								 | 
							
										((para->cs_num >> 1) << 4) |
							 | 
						||
| 
								 | 
							
										((para->row_width - 1) << 5) |
							 | 
						||
| 
								 | 
							
										((para->col_width - 1) << 9) |
							 | 
						||
| 
								 | 
							
										((para->sdr_ddr ? (para->bwidth >> 4) : (para->bwidth >> 5)) << 13) |
							 | 
						||
| 
								 | 
							
										(para->access_mode << 15) |
							 | 
						||
| 
								 | 
							
										(para->sdr_ddr << 16);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									write32(F1C100S_DRAM_BASE + DRAM_SCONR, val);
							 | 
						||
| 
								 | 
							
									write32(F1C100S_DRAM_BASE + DRAM_SCTLR, read32(F1C100S_DRAM_BASE + DRAM_SCTLR) | (0x1 << 19));
							 | 
						||
| 
								 | 
							
									return dram_initial();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t dram_check_delay(uint32_t bwidth)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									uint32_t dsize;
							 | 
						||
| 
								 | 
							
									uint32_t i,j;
							 | 
						||
| 
								 | 
							
									uint32_t num = 0;
							 | 
						||
| 
								 | 
							
									uint32_t dflag = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									dsize = ((bwidth == 16) ? 4 : 2);
							 | 
						||
| 
								 | 
							
									for(i = 0; i < dsize; i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(i == 0)
							 | 
						||
| 
								 | 
							
											dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR0);
							 | 
						||
| 
								 | 
							
										else if(i == 1)
							 | 
						||
| 
								 | 
							
											dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR1);
							 | 
						||
| 
								 | 
							
										else if(i == 2)
							 | 
						||
| 
								 | 
							
											dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR2);
							 | 
						||
| 
								 | 
							
										else if(i == 3)
							 | 
						||
| 
								 | 
							
											dflag = read32(F1C100S_DRAM_BASE + DRAM_DRPTR3);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for(j = 0; j < 32; j++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if(dflag & 0x1)
							 | 
						||
| 
								 | 
							
												num++;
							 | 
						||
| 
								 | 
							
											dflag >>= 1;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return num;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int sdr_readpipe_scan(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									uint32_t k = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for(k = 0; k < 32; k++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										write32(0x80000000 + 4 * k, k);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for(k = 0; k < 32; k++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(read32(0x80000000 + 4 * k) != k)
							 | 
						||
| 
								 | 
							
											return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t sdr_readpipe_select(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									uint32_t value = 0;
							 | 
						||
| 
								 | 
							
									uint32_t i = 0;
							 | 
						||
| 
								 | 
							
									for(i = 0; i < 8; i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										write32(F1C100S_DRAM_BASE + DRAM_SCTLR, (read32(F1C100S_DRAM_BASE + DRAM_SCTLR) & (~(0x7 << 6))) | (i << 6));
							 | 
						||
| 
								 | 
							
										if(sdr_readpipe_scan())
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											value = i;
							 | 
						||
| 
								 | 
							
											return value;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return value;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t dram_check_type(struct dram_para_t * para)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									uint32_t val = 0;
							 | 
						||
| 
								 | 
							
									uint32_t times = 0;
							 | 
						||
| 
								 | 
							
									uint32_t i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for(i = 0; i < 8; i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR);
							 | 
						||
| 
								 | 
							
										val &= ~(0x7 << 6);
							 | 
						||
| 
								 | 
							
										val |= (i << 6);
							 | 
						||
| 
								 | 
							
										write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										dram_delay_scan();
							 | 
						||
| 
								 | 
							
										if(read32(F1C100S_DRAM_BASE + DRAM_DDLYR) & 0x30)
							 | 
						||
| 
								 | 
							
											times++;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(times == 8)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										para->sdr_ddr = DRAM_TYPE_SDR;
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										para->sdr_ddr = DRAM_TYPE_DDR;
							 | 
						||
| 
								 | 
							
										return 1;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t dram_scan_readpipe(struct dram_para_t * para)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									uint32_t i, rp_best = 0, rp_val = 0;
							 | 
						||
| 
								 | 
							
									uint32_t val = 0;
							 | 
						||
| 
								 | 
							
									uint32_t readpipe[8];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(para->sdr_ddr == DRAM_TYPE_DDR)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for(i = 0; i < 8; i++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR);
							 | 
						||
| 
								 | 
							
											val &= ~(0x7 << 6);
							 | 
						||
| 
								 | 
							
											val |= (i << 6);
							 | 
						||
| 
								 | 
							
											write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val);
							 | 
						||
| 
								 | 
							
											dram_delay_scan();
							 | 
						||
| 
								 | 
							
											readpipe[i] = 0;
							 | 
						||
| 
								 | 
							
											if((((read32(F1C100S_DRAM_BASE + DRAM_DDLYR) >> 4) & 0x3) == 0x0) &&
							 | 
						||
| 
								 | 
							
												(((read32(F1C100S_DRAM_BASE + DRAM_DDLYR) >> 4) & 0x1) == 0x0))
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												readpipe[i] = dram_check_delay(para->bwidth);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if(rp_val < readpipe[i])
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												rp_val = readpipe[i];
							 | 
						||
| 
								 | 
							
												rp_best = i;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR);
							 | 
						||
| 
								 | 
							
										val &= ~(0x7 << 6);
							 | 
						||
| 
								 | 
							
										val |= (rp_best << 6);
							 | 
						||
| 
								 | 
							
										write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val);
							 | 
						||
| 
								 | 
							
										dram_delay_scan();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										val = read32(F1C100S_DRAM_BASE + DRAM_SCONR);
							 | 
						||
| 
								 | 
							
										val &= (~(0x1 << 16));
							 | 
						||
| 
								 | 
							
										val &= (~(0x3 << 13));
							 | 
						||
| 
								 | 
							
										write32(F1C100S_DRAM_BASE + DRAM_SCONR, val);
							 | 
						||
| 
								 | 
							
										rp_best = sdr_readpipe_select();
							 | 
						||
| 
								 | 
							
										val = read32(F1C100S_DRAM_BASE + DRAM_SCTLR);
							 | 
						||
| 
								 | 
							
										val &= ~(0x7 << 6);
							 | 
						||
| 
								 | 
							
										val |= (rp_best << 6);
							 | 
						||
| 
								 | 
							
										write32(F1C100S_DRAM_BASE + DRAM_SCTLR, val);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t dram_get_dram_size(struct dram_para_t * para)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									uint32_t colflag = 10, rowflag = 13;
							 | 
						||
| 
								 | 
							
									uint32_t i = 0;
							 | 
						||
| 
								 | 
							
									uint32_t val1 = 0;
							 | 
						||
| 
								 | 
							
									uint32_t count = 0;
							 | 
						||
| 
								 | 
							
									uint32_t addr1, addr2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									para->col_width = colflag;
							 | 
						||
| 
								 | 
							
									para->row_width = rowflag;
							 | 
						||
| 
								 | 
							
									dram_para_setup(para);
							 | 
						||
| 
								 | 
							
									dram_scan_readpipe(para);
							 | 
						||
| 
								 | 
							
									for(i = 0; i < 32; i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										*((uint32_t *)(0x80000200 + i)) = 0x11111111;
							 | 
						||
| 
								 | 
							
										*((uint32_t *)(0x80000600 + i)) = 0x22222222;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for(i = 0; i < 32; i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										val1 = *((uint32_t *)(0x80000200 + i));
							 | 
						||
| 
								 | 
							
										if(val1 == 0x22222222)
							 | 
						||
| 
								 | 
							
											count++;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(count == 32)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										colflag = 9;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										colflag = 10;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									count = 0;
							 | 
						||
| 
								 | 
							
									para->col_width = colflag;
							 | 
						||
| 
								 | 
							
									para->row_width = rowflag;
							 | 
						||
| 
								 | 
							
									dram_para_setup(para);
							 | 
						||
| 
								 | 
							
									if(colflag == 10)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										addr1 = 0x80400000;
							 | 
						||
| 
								 | 
							
										addr2 = 0x80c00000;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										addr1 = 0x80200000;
							 | 
						||
| 
								 | 
							
										addr2 = 0x80600000;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for(i = 0; i < 32; i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										*((uint32_t *)(addr1 + i)) = 0x33333333;
							 | 
						||
| 
								 | 
							
										*((uint32_t *)(addr2 + i)) = 0x44444444;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for(i = 0; i < 32; i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										val1 = *((uint32_t *)(addr1 + i));
							 | 
						||
| 
								 | 
							
										if(val1 == 0x44444444)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											count++;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(count == 32)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										rowflag = 12;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										rowflag = 13;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									para->col_width = colflag;
							 | 
						||
| 
								 | 
							
									para->row_width = rowflag;
							 | 
						||
| 
								 | 
							
									if(para->row_width != 13)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										para->size = 16;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if(para->col_width == 10)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										para->size = 64;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										para->size = 32;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									dram_set_autofresh_cycle(para->clk);
							 | 
						||
| 
								 | 
							
									para->access_mode = 0;
							 | 
						||
| 
								 | 
							
									dram_para_setup(para);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int dram_init(struct dram_para_t * para)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									uint32_t val = 0;
							 | 
						||
| 
								 | 
							
									uint32_t i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									write32(0x01c20800 + 0x24, read32(0x01c20800 + 0x24) | (0x7 << 12));
							 | 
						||
| 
								 | 
							
									dram_delay(5);
							 | 
						||
| 
								 | 
							
									if(((para->cas) >> 3) & 0x1)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										write32(0x01c20800 + 0x2c4, read32(0x01c20800 + 0x2c4) | (0x1 << 23) | (0x20 << 17));
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if((para->clk >= 144) && (para->clk <= 180))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										write32(0x01c20800 + 0x2c0, 0xaaa);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(para->clk >= 180)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										write32(0x01c20800 + 0x2c0, 0xfff);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if((para->clk) <= 96)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										val = (0x1 << 0) | (0x0 << 4) | (((para->clk * 2) / 12 - 1) << 8) | (0x1u << 31);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										val = (0x0 << 0) | (0x0 << 4) | (((para->clk * 2) / 24 - 1) << 8) | (0x1u << 31);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(para->cas & (0x1 << 4))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xd1303333);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if(para->cas & (0x1 << 5))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xcce06666);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if(para->cas & (0x1 << 6))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xc8909999);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if(para->cas & (0x1 << 7))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										write32(F1C100S_CCU_BASE + CCU_PLL_DDR0_PAT, 0xc440cccc);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(para->cas & (0xf << 4))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										val |= 0x1 << 24;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									write32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL, val);
							 | 
						||
| 
								 | 
							
									write32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL, read32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL) | (0x1 << 20));
							 | 
						||
| 
								 | 
							
									while((read32(F1C100S_CCU_BASE + CCU_PLL_DDR_CTRL) & (1 << 28)) == 0);
							 | 
						||
| 
								 | 
							
									dram_delay(5);
							 | 
						||
| 
								 | 
							
									write32(F1C100S_CCU_BASE + CCU_BUS_CLK_GATE0, read32(F1C100S_CCU_BASE + CCU_BUS_CLK_GATE0) | (0x1 << 14));
							 | 
						||
| 
								 | 
							
									write32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0, read32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0) & ~(0x1 << 14));
							 | 
						||
| 
								 | 
							
									for(i = 0; i < 10; i++)
							 | 
						||
| 
								 | 
							
										continue;
							 | 
						||
| 
								 | 
							
									write32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0, read32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0) | (0x1 << 14));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									val = read32(0x01c20800 + 0x2c4);
							 | 
						||
| 
								 | 
							
									(para->sdr_ddr == DRAM_TYPE_DDR) ? (val |= (0x1 << 16)) : (val &= ~(0x1 << 16));
							 | 
						||
| 
								 | 
							
									write32(0x01c20800 + 0x2c4, val);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									val = (SDR_T_CAS << 0) | (SDR_T_RAS << 3) | (SDR_T_RCD << 7) | (SDR_T_RP << 10) | (SDR_T_WR << 13) | (SDR_T_RFC << 15) | (SDR_T_XSR << 19) | (SDR_T_RC << 28);
							 | 
						||
| 
								 | 
							
									write32(F1C100S_DRAM_BASE + DRAM_STMG0R, val);
							 | 
						||
| 
								 | 
							
									val = (SDR_T_INIT << 0) | (SDR_T_INIT_REF << 16) | (SDR_T_WTR << 20) | (SDR_T_RRD << 22) | (SDR_T_XP << 25);
							 | 
						||
| 
								 | 
							
									write32(F1C100S_DRAM_BASE + DRAM_STMG1R, val);
							 | 
						||
| 
								 | 
							
									dram_para_setup(para);
							 | 
						||
| 
								 | 
							
									dram_check_type(para);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									val = read32(0x01c20800 + 0x2c4);
							 | 
						||
| 
								 | 
							
									(para->sdr_ddr == DRAM_TYPE_DDR) ? (val |= (0x1 << 16)) : (val &= ~(0x1 << 16));
							 | 
						||
| 
								 | 
							
									write32(0x01c20800 + 0x2c4, val);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									dram_set_autofresh_cycle(para->clk);
							 | 
						||
| 
								 | 
							
									dram_scan_readpipe(para);
							 | 
						||
| 
								 | 
							
									dram_get_dram_size(para);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for(i = 0; i < 128; i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										*((volatile uint32_t *)(para->base + 4 * i)) = para->base + 4 * i;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for(i = 0; i < 128; i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if(*((volatile uint32_t *)(para->base + 4 * i)) != (para->base + 4 * i))
							 | 
						||
| 
								 | 
							
											return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void sys_dram_init(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									struct dram_para_t para;
							 | 
						||
| 
								 | 
							
									uint32_t * dsz = (void *)0x0000005c;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									para.base = 0x80000000;
							 | 
						||
| 
								 | 
							
									para.size = 32;
							 | 
						||
| 
								 | 
							
									para.clk = PLL_DDR_CLK / 1000000;
							 | 
						||
| 
								 | 
							
									para.access_mode = 1;
							 | 
						||
| 
								 | 
							
									para.cs_num = 1;
							 | 
						||
| 
								 | 
							
									para.ddr8_remap = 0;
							 | 
						||
| 
								 | 
							
									para.sdr_ddr = DRAM_TYPE_DDR;
							 | 
						||
| 
								 | 
							
									para.bwidth = 16;
							 | 
						||
| 
								 | 
							
									para.col_width = 10;
							 | 
						||
| 
								 | 
							
									para.row_width = 13;
							 | 
						||
| 
								 | 
							
									para.bank_size = 4;
							 | 
						||
| 
								 | 
							
									para.cas = 0x3;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if((dsz[0] >> 24) == 'X')
							 | 
						||
| 
								 | 
							
										return;
							 | 
						||
| 
								 | 
							
									if(dram_init(¶))
							 | 
						||
| 
								 | 
							
										dsz[0] = (((uint32_t)'X') << 24) | (para.size << 0);
							 | 
						||
| 
								 | 
							
								}
							 |