cmd_pati.c

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

C
450
字号
/*
 * (C) Copyright 2001
 * Denis Peter, MPL AG Switzerland, 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
 *
 * Adapted for PATI
 */

#include <common.h>
#include <command.h>
#define PLX9056_LOC
#include "plx9056.h"
#include "pati.h"
#include "pci_eeprom.h"

extern void show_pld_regs(void);
extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);

extern void user_led0(int led_on);
extern void user_led1(int led_on);

/* ------------------------------------------------------------------------- */
#if defined(CFG_PCI_CON_DEVICE)
extern void pci_con_disc(void);
extern void pci_con_connect(void);
#endif

/******************************************************************************
 * Eeprom Support
 ******************************************************************************/
unsigned long get32(unsigned long addr)
{
	unsigned long *p=(unsigned long *)addr;
	return *p;
}

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

#define PCICFG_GET_REG(x)	(get32((x) + PCI_CONFIG_BASE))
#define PCICFG_SET_REG(x,y)	(set32((x) + PCI_CONFIG_BASE,(y)))


/******************************************************************************
 * reload_pci_eeprom
 ******************************************************************************/

static void reload_pci_eeprom(void)
{
	unsigned long reg;
	/* Set Bit 29 and clear it again */
	reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
	udelay(1);
	/* set it*/
	reg|=(1<<29);
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
	/* EECLK @ 33MHz = 125kHz
	 * -> extra long load = 32 * 16bit = 512Bit @ 125kHz = 4.1msec
	 * use 20msec
	 */
	udelay(20000); /* wait 20ms */
	reg &= ~(1<<29); /* set it low */
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
	udelay(1); /* wait some time */
}

/******************************************************************************
 * clock_pci_eeprom
 ******************************************************************************/

static void clock_pci_eeprom(void)
{
	unsigned long reg;
	/* clock is low, data is valid */
	reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
	udelay(1);
	/* set clck high */
	reg|=(1<<24);
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
	udelay(1); /* wait some time */
	reg &= ~(1<<24); /* set clock low */
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
	udelay(1); /* wait some time */
}

/******************************************************************************
 * send_pci_eeprom_cmd
 ******************************************************************************/
static void send_pci_eeprom_cmd(unsigned long cmd, unsigned char len)
{
	unsigned long reg;
	int i;
	reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
	/* Clear all EEPROM bits */
	reg &= ~(0xF << 24);
	/* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
	udelay(1); /* wait some time */
	/* Enable EEPROM Chip Select */
	reg |= (1 << 25);
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
	/* Send EEPROM command - one bit at a time */
	for (i = (int)(len-1); i >= 0; i--) {
		/* Check if current bit is 0 or 1 */
		if (cmd & (1 << i))
			PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,(reg | (1<<26)));
		else
			PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
		clock_pci_eeprom();
	}
}

/******************************************************************************
 * write_pci_eeprom_offs
 ******************************************************************************/
static void write_pci_eeprom_offs(unsigned short offset, unsigned short value)
{
	unsigned long reg;
	int bitpos, cmdshft, cmdlen, timeout;
	/* we're using the Eeprom 93CS66 */
	cmdshft  = 2;
	cmdlen = EE66_CMD_LEN;
	/* Send Write_Enable command to EEPROM */
	send_pci_eeprom_cmd((EE_WREN << cmdshft),cmdlen);
	/* Send EEPROM Write command and offset to EEPROM */
	send_pci_eeprom_cmd((EE_WRITE << cmdshft) | (offset / 2),cmdlen);
	reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
	/* Clear all EEPROM bits */
	reg &= ~(0xF << 24);
	/* Make sure EEDO Input is disabled for some PLX chips */
	reg &= ~(1 << 31);
	/* Enable EEPROM Chip Select */
	reg |= (1 << 25);
	/* Write 16-bit value to EEPROM - one bit at a time */
	for (bitpos = 15; bitpos >= 0; bitpos--) {
		/* Get bit value and shift into result */
		if (value & (1 << bitpos))
			PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,(reg | (1<<26)));
		else
			PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg );
		clock_pci_eeprom();
	} /* for */
	/* Deselect Chip */
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(1 << 25));
	/* Re-select Chip */
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg | (1 << 25));
	/* A small delay is needed to let EEPROM complete */
	timeout = 0;
	do {
		udelay(10);
		reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
		timeout++;
	} while (((reg & (1 << 27)) == 0) && timeout < 20000);
	/* Send Write_Disable command to EEPROM */
	send_pci_eeprom_cmd((EE_WDS << cmdshft),cmdlen);
	/* Clear Chip Select and all other EEPROM bits */
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(0xF << 24));
}


/******************************************************************************
 * read_pci_eeprom_offs
 ******************************************************************************/
static void read_pci_eeprom_offs(unsigned short offset, unsigned short *pvalue)
{
	unsigned long reg;
	int bitpos, cmdshft, cmdlen;
	/* we're using the Eeprom 93CS66 */
	cmdshft  = 2;
	cmdlen = EE66_CMD_LEN;
	/* Send EEPROM read command and offset to EEPROM */
	send_pci_eeprom_cmd((EE_READ << cmdshft) | (offset / 2),cmdlen);
	/* Set EEPROM write output bit */
	reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
	/* Set EEDO Input enable */
	reg |= (1 << 31);
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg | (1 << 26));
	/* Get 16-bit value from EEPROM - one bit at a time */
	for (bitpos = 0; bitpos < 16; bitpos++) {
		clock_pci_eeprom();
		udelay(10);
		reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
		/* Get bit value and shift into result */
		if (reg & (1 << 27))
			*pvalue = (unsigned short)((*pvalue << 1) | 1);
		else
			*pvalue = (unsigned short)(*pvalue << 1);
	}
	/* Clear EEDO Input enable */
	reg &= ~(1 << 31);
	/* Clear Chip Select and all other EEPROM bits */
	PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(0xF << 24));
}


/******************************************************************************
 * EEPROM read/writes
******************************************************************************/

#undef EEPROM_DBG
static int pati_pci_eeprom_erase(void)
{
	int i;
	printf("Erasing EEPROM ");
	for( i=0; i < PATI_EEPROM_LAST_OFFSET; i+=2) {

⌨️ 快捷键说明

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