pati.c

来自「适合KS8695X」· C语言 代码 · 共 619 行 · 第 1/2 页

C
619
字号
/*
 * (C) Copyright 2003
 * Martin Winistoerfer, martinwinistoerfer@gmx.ch.
 * Atapted for PATI
 * Denis Peter, d.peter@mpl.ch
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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
 */

/***********************************************************************************
 * Bits for the SDRAM controller
 * -----------------------------
 *
 * CAL:	CAS Latency. If cleared to 0 (default) the SDRAM controller asserts TA# on
 *	the 2nd Clock after ACTIVE command (CAS Latency = 2). If set to 1 the SDRAM
 *	controller asserts TA# on the 3rd Clock after ACTIVE command (CAS Latency = 3).
 * RCD:	RCD ACTIVE to READ or WRITE Delay (Ras to Cas Delay). If cleared 0 (default)
 *	tRCD of the SDRAM must equal or less 25ns. If set to 1 tRCD must be equal or less 50ns.
 * WREC:Write Recovery. If cleared 0 (default) tWR of the SDRAM must equal or less 25ns.
 *	If set to 1 tWR must be equal or less 50ns.
 * RP:	Precharge Command Time. If cleared 0 (default) tRP of the SDRAM must equal or less
 *	25ns. If set to 1 tRP must be equal or less 50ns.
 * RC:	Auto Refresh to Active Time. If cleared 0 (default) tRC of the SDRAM must equal
 *	or less 75ns. If set to 1 tRC must be equal or less 100ns.
 * LMR:	Bit to set the Mode Register of the SDRAM. If set, the next access to the SDRAM
 *	is the Load Mode Register Command.
 * IIP:	Init in progress. Set to 1 for starting the init sequence
 *	(Precharge All). As long this bit is set, the Precharge All is still in progress.
 *	After command has completed, wait at least for 8 refresh (200usec) before proceed.
 **********************************************************************************/

#include <common.h>
#include <mpc5xx.h>
#include <devices.h>
#include <pci_ids.h>
#define PLX9056_LOC
#include "plx9056.h"
#include "pati.h"

#if defined(__APPLE__)
/* Leading underscore on symbols */
#  define SYM_CHAR "_"
#else /* No leading character on symbols */
#  define SYM_CHAR
#endif

#undef SDRAM_DEBUG
/*
 * Macros to generate global absolutes.
 */
#define GEN_SYMNAME(str) SYM_CHAR #str
#define GEN_VALUE(str) #str
#define GEN_ABS(name, value) \
		asm (".globl " GEN_SYMNAME(name)); \
		asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))


/************************************************************************
 * Early debug routines
 */
void write_hex (unsigned char i)
{
	char cc;

	cc = i >> 4;
	cc &= 0xf;
	if (cc > 9)
		serial_putc (cc + 55);
	else
		serial_putc (cc + 48);
	cc = i & 0xf;
	if (cc > 9)
		serial_putc (cc + 55);
	else
		serial_putc (cc + 48);
}

#if defined(SDRAM_DEBUG)

void write_4hex (unsigned long val)
{
	write_hex ((unsigned char) (val >> 24));
	write_hex ((unsigned char) (val >> 16));
	write_hex ((unsigned char) (val >> 8));
	write_hex ((unsigned char) val);
}

#endif

unsigned long in32(unsigned long addr)
{
	unsigned long *p=(unsigned long *)addr;
	return *p;
}

void out32(unsigned long addr,unsigned long data)
{
	unsigned long *p=(unsigned long *)addr;
	*p=data;
}

typedef struct {
	unsigned short boardtype; /* Board revision and Population Options */
	unsigned char cal;		/* cas Latency  0:CAL=2 1:CAL=3 */
	unsigned char rcd;		/* ras to cas delay  0:<25ns 1:<50ns*/
	unsigned char wrec;		/* write recovery 0:<25ns 1:<50ns */
	unsigned char pr;		/* Precharge Command Time 0:<25ns 1:<50ns */
	unsigned char rc;		/* Auto Refresh to Active Time 0:<75ns 1:<100ns */
	unsigned char sz;		/* log binary => Size = (4MByte<<sz) 5 = 128, 4 = 64, 3 = 32, 2 = 16, 1=8 */
} sdram_t;

const sdram_t sdram_table[] = {
	{ 0x0000,	/* PATI Rev A, 16MByte -1 Board */
		1,	/* Case Latenty = 3 */
		0,	/* ras to cas delay  0 (20ns) */
		0,	/* write recovery 0:<25ns 1:<50ns*/
		0,	/* Precharge Command Time 0 (20ns) */
		0,	/* Auto Refresh to Active Time 0 (68) */
		2	/* log binary => Size 2 = 16MByte, 1=8 */
	},
	{ 0xffff, /* terminator */
	  0xff,
	  0xff,
	  0xff,
	  0xff,
	  0xff,
	  0xff }
};


extern int mem_test (unsigned long start, unsigned long ramsize, int quiet);
extern void mem_test_reloc(void);

/*
 * Get RAM size.
 */
long int initdram(int board_type)
{
	unsigned char board_rev;
	unsigned long reg;
	unsigned long lmr;
	int i,timeout;

#if defined(SDRAM_DEBUG)
	reg=in32(PLD_CONFIG_BASE+PLD_PART_ID);
	puts("\n\nSYSTEM part 0x"); write_4hex(SYSCNTR_PART(reg));
	puts(" Vers 0x"); write_4hex(SYSCNTR_ID(reg));
	puts("\nSDRAM  part  0x"); write_4hex(SDRAM_PART(reg));
	puts(" Vers 0x"); write_4hex(SDRAM_ID(reg));
	reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
	puts("\nBoard rev.   0x"); write_4hex(SYSCNTR_BREV(reg));
   putc('\n');
#endif
	reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
	board_rev=(unsigned char)(SYSCNTR_BREV(reg));
	i=0;
	while(1) {
		if(sdram_table[i].boardtype==0xffff) {
			puts("ERROR, found no table for Board 0x");
			write_hex(board_rev);
			while(1);
		}
		if(sdram_table[i].boardtype==(unsigned char)board_rev)
			break;
		i++;
	}
	/* Set CAL, RCD, WREQ, PR and RC Bits */
#if defined(SDRAM_DEBUG)
	puts("Set CAL, RCD, WREQ, PR and RC Bits\n");
#endif
	/* mask bits */
	reg &= ~(SET_REG_BIT(1,SDRAM_CAL) | SET_REG_BIT(1,SDRAM_RCD) | SET_REG_BIT(1,SDRAM_WREQ) |
				SET_REG_BIT(1,SDRAM_PR)  |  SET_REG_BIT(1,SDRAM_RC) | SET_REG_BIT(1,SDRAM_LMR)  |
				SET_REG_BIT(1,SDRAM_IIP) | SET_REG_BIT(1,SDRAM_RES0));
	/* set bits */
	reg |= (SET_REG_BIT(sdram_table[i].cal,SDRAM_CAL) |
			  SET_REG_BIT(sdram_table[i].rcd,SDRAM_RCD) |
			  SET_REG_BIT(sdram_table[i].wrec,SDRAM_WREQ) |
			  SET_REG_BIT(sdram_table[i].pr,SDRAM_PR) |
			  SET_REG_BIT(sdram_table[i].rc,SDRAM_RC));

	out32(PLD_CONFIG_BASE+PLD_BOARD_TIMING,reg);
	/* step 2 set IIP */
#if defined(SDRAM_DEBUG)
	puts("step 2 set IIP\n");
#endif
	/* step 2 set IIP */
	reg |= SET_REG_BIT(1,SDRAM_IIP);
	timeout=0;
	while (timeout!=0xffff) {
		__asm__ volatile("eieio");
		reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
		if((reg & SET_REG_BIT(1,SDRAM_IIP))==0)
			break;
		timeout++;
		udelay(1);
	}
	/* wait for at least 8 refresh */
	udelay(1000);
	/* set LMR */
	reg |= SET_REG_BIT(1,SDRAM_LMR);
	out32(PLD_CONFIG_BASE+PLD_BOARD_TIMING,reg);
	__asm__ volatile("eieio");
	lmr=0x00000002; /* sequential burst 4 data */
	if(sdram_table[i].cal==1)
		lmr|=0x00000030; /* cal = 3 */
	else
		lmr|=0000000020; /* cal = 2 */
	/* rest standard operation programmed write burst length */
	/* we have a x32 bit bus to the SDRAM, so shift the addr with 2 */
	lmr<<=2;
	in32(CFG_SDRAM_BASE + lmr);
	/* ok, we're done, return SDRAM size */
	return ((0x400000 << sdram_table[i].sz));		/* log2 value of 4MByte  */
}


void set_flash_vpp(int ext_vpp, int ext_wp, int int_vpp)
{
	unsigned long reg;
	reg=in32(PLD_CONF_REG2+PLD_CONFIG_BASE);
	reg &= ~(SET_REG_BIT(1,SYSCNTR_CPU_VPP) |
			   SET_REG_BIT(1,SYSCNTR_FL_VPP) |
				SET_REG_BIT(1,SYSCNTR_FL_WP));

	reg |= (SET_REG_BIT(int_vpp,SYSCNTR_CPU_VPP) |
			   SET_REG_BIT(ext_vpp,SYSCNTR_FL_VPP) |
				SET_REG_BIT(ext_wp,SYSCNTR_FL_WP));
	out32(PLD_CONF_REG2+PLD_CONFIG_BASE,reg);
	udelay(100);
}


void show_pld_regs(void)
{
	unsigned long reg,reg1;
	reg=in32(PLD_CONFIG_BASE+PLD_PART_ID);
	printf("\nSYSTEM part %ld, Vers %ld\n",SYSCNTR_PART(reg),SYSCNTR_ID(reg));
	printf("SDRAM  part %ld, Vers %ld\n",SDRAM_PART(reg),SDRAM_ID(reg));
	reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING);
	printf("Board rev.  %c\n",(char) (SYSCNTR_BREV(reg)+'A'));
	printf("Waitstates  %ld\n",GET_SYSCNTR_FLWAIT(reg));
	printf("SDRAM:      CAL=%ld RCD=%ld WREQ=%ld PR=%ld\n            RC=%ld  LMR=%ld IIP=%ld\n",
		GET_REG_BIT(reg,SDRAM_CAL),GET_REG_BIT(reg,SDRAM_RCD),
		GET_REG_BIT(reg,SDRAM_WREQ),GET_REG_BIT(reg,SDRAM_PR),
		GET_REG_BIT(reg,SDRAM_RC),GET_REG_BIT(reg,SDRAM_LMR),
		GET_REG_BIT(reg,SDRAM_IIP));
	reg=in32(PLD_CONFIG_BASE+PLD_CONF_REG1);
	reg1=in32(PLD_CONFIG_BASE+PLD_CONF_REG2);
	printf("HW Config:  FLAG=%ld IP=%ld  index=%ld PRPM=%ld\n            ICW=%ld  ISB=%ld BDIS=%ld  PCIM=%ld\n",
		GET_REG_BIT(reg,SYSCNTR_FLAG),GET_REG_BIT(reg,SYSCNTR_IP),
		GET_SYSCNTR_BOOTIND(reg),GET_REG_BIT(reg,SYSCNTR_PRM),
		GET_REG_BIT(reg,SYSCNTR_ICW),GET_SYSCNTR_ISB(reg),
		GET_REG_BIT(reg1,SYSCNTR_BDIS),GET_REG_BIT(reg1,SYSCNTR_PCIM));
	printf("Switches:   MUX=%ld PCI_DIS=%ld Boot_EN=%ld  Config=%ld\n",GET_SDRAM_MUX(reg),
		GET_REG_BIT(reg,SDRAM_PDIS),GET_REG_BIT(reg1,SYSCNTR_BOOTEN),
		GET_SYSCNTR_CFG(reg1));
	printf("Misc:       RIP=%ld CPU_VPP=%ld FLSH_VPP=%ld FLSH_WP=%ld\n\n",
		GET_REG_BIT(reg,SDRAM_RIP),GET_REG_BIT(reg1,SYSCNTR_CPU_VPP),
		GET_REG_BIT(reg1,SYSCNTR_FL_VPP),GET_REG_BIT(reg1,SYSCNTR_FL_WP));
}


/****************************************************************
 * Setting IOs
 * -----------
 * GPIO6 is User LED1
 * GPIO7 is Interrupt PLX (Output)
 * GPIO5 is User LED0
 * GPIO2 is PLX USERi (Output)
 * GPIO1 is PLX Interrupt (Input)
 ****************************************************************/
 void init_ios(void)
 {
	volatile immap_t * immr = (immap_t *) CFG_IMMR;
	volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
	unsigned long reg;
	reg=sysconf->sc_sgpiocr; /* Data direction register */
	reg &= ~0x67000000;
	reg |= 0x27000000; /* set outpupts */
	sysconf->sc_sgpiocr=reg; /* Data direction register */
	reg=sysconf->sc_sgpiodt2; /* Data register */
	/* set output to 0 */
	reg &= ~0x27000000;
	/* set IRQ and USERi to 1 */
	reg |= 0x28000000;
	sysconf->sc_sgpiodt2=reg; /* Data register */
}

void user_led0(int led_on)
{
	volatile immap_t * immr = (immap_t *) CFG_IMMR;
	volatile sysconf5xx_t *sysconf = &immr->im_siu_conf;
	unsigned long reg;
	reg=sysconf->sc_sgpiodt2; /* Data register */

⌨️ 快捷键说明

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