⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atlas_malta.s

📁 yamon2.27.tar.gz bootloader 在au1200上完全通过
💻 S
字号:
	
/************************************************************************
 *
 *  atlas_malta.S
 *
 *  Atlas and Malta specific initialisation
 *
 *
 * ######################################################################
 *
 * Copyright (c) 1999-2000 MIPS Technologies, Inc. All rights reserved. 
 * 
 * Unpublished rights reserved under the Copyright Laws of the United States of 
 * America. 
 * 
 * This document contains information that is proprietary to MIPS Technologies, 
 * Inc. ("MIPS Technologies"). Any copying, modifying or use of this information 
 * (in whole or in part) which is not expressly permitted in writing by MIPS 
 * Technologies or a contractually-authorized third party is strictly 
 * prohibited. At a minimum, this information is protected under unfair 
 * competition laws and the expression of the information contained herein is 
 * protected under federal copyright laws. Violations thereof may result in 
 * criminal penalties and fines. 
 * MIPS Technologies or any contractually-authorized third party reserves the 
 * right to change the information contained in this document to improve 
 * function, design or otherwise. MIPS Technologies does not assume any 
 * liability arising out of the application or use of this information. Any 
 * license under patent rights or any other intellectual property rights owned 
 * by MIPS Technologies or third parties shall be conveyed by MIPS Technologies 
 * or any contractually-authorized third party in a separate license agreement 
 * between the parties. 
 * The information contained in this document constitutes one or more of the 
 * following: commercial computer software, commercial computer software 
 * documentation or other commercial items. If the user of this information, or 
 * any related documentation of any kind, including related technical data or 
 * manuals, is an agency, department, or other entity of the United States 
 * government ("Government"), the use, duplication, reproduction, release, 
 * modification, disclosure, or transfer of this information, or any related 
 * documentation of any kind, is restricted in accordance with Federal 
 * Acquisition Regulation 12.212 for civilian agencies and Defense Federal 
 * Acquisition Regulation Supplement 227.7202 for military agencies. The use of 
 * this information by the Government is further restricted in accordance with 
 * the terms of the license agreement(s) and/or applicable contract terms and 
 * conditions covering this information from MIPS Technologies or any 
 * contractually-authorized third party. 
 *
 ************************************************************************/


/************************************************************************
 *  Include files
 ************************************************************************/

#include <sysdefs.h>
#include <mips.h>
#include <pci_api.h>
#include <i2c.h>
#include <init.h>
#include <product.h>	
#include <atlas.h>
#include <malta.h>
#include <saa9730.h>  /* Atlas specific */
	
/************************************************************************
 *  Definitions
 ************************************************************************/

/**** Display platform. Modifies t9..t5 (due to DISP_STR) and t0 ****/
	
#define DISP_PLATFORM		      \
	li	t0, PRODUCT_MALTA_ID; \
	beq	t0, k0, 1f;	      \
	nop;			      \
	DISP_STR( msg_atlas );	      \
	b	2f;		      \
	nop;			      \
1:				      \
	DISP_STR( msg_malta );        \
2:

/******** Definitions for I2C controller on Malta ********/

#define SCL_TX		MALTA_I2COE_I2CSCL_BIT
#define SCL_RX		0
#define SDA_TX		MALTA_I2COE_I2CSDA_BIT
#define SDA_RX		0

#define SCL_HI		MALTA_I2COUT_I2CSCL_BIT
#define SCL_LO		0
#define SDA_HI		MALTA_I2COUT_I2CSDA_BIT
#define SDA_LO		0

/*  Loop counter for PAUSE loop :
 *
 *  Each iteration of loop consists of two instructions, i.e. two 
 *  processor clock cycles (assuming cached operation).
 *
 *  A pause loop should delay the processor half an I2C clock cycle.
 *
 *  We assume a max. processor frequency of 1000MHz.
 */
#define PAUSE_COUNT (1000000 / MAX_I2C_FREQ_KHZ  / 2 / 2)

#define PAUSE				          \
	    li    t7, PAUSE_COUNT;		  \
10:						  \
	    bne   t7, zero, 10b;		  \
	    addiu t7, -1

#define I2C_DIRECTION( scl, sda )	          \
	    li t7, KSEG1(MALTA_I2COE);		  \
	    li t6, (scl) | (sda);		  \
	    sw t6, 0(t7);			  \
	    PAUSE

#define I2C_TX( scl, sda )		          \
	    li t7, KSEG1(MALTA_I2COUT);		  \
	    li t6, (scl) | (sda);		  \
	    sw t6, 0(t7);			  \
	    PAUSE

#define I2C_RX( reg )				  \
	    li   t7, KSEG1(MALTA_I2CINP);	  \
	    lw   reg, 0(t7);			  \
	    andi reg, MALTA_I2CINP_I2CSDA_MSK;	  \
	    srl  reg, MALTA_I2CINP_I2CSDA_SHF;	  \
	    PAUSE

#define I2C_FPGA_ENABLE		                  \
	    li t7, KSEG1(MALTA_I2COE);		  \
	    li t6, (SCL_RX) | (SDA_RX);		  \
	    sw t6, 0(t7);			  \
	    li t7, KSEG1(MALTA_I2COUT);		  \
	    li t6, (SCL_HI) | (SDA_HI);		  \
	    sw t6, 0(t7);			  \
	    li t7, KSEG1(MALTA_I2CSEL);		  \
	    li t6, MALTA_I2CSEL_FPGA_BIT;	  \
	    sw t6, 0(t7);			  \
	    PAUSE
	
/************************************************************************
 *  Public variables
 ************************************************************************/

/************************************************************************
 *  Static variables
 ************************************************************************/

/************************************************************************
 *  Implementation : Public functions
 ************************************************************************/
	
	
/************************************************************************	
 *
 *                          sys_init_atlas_malta
 *  Description :
 *  -------------
 *
 *  Determine SDRAM parameters and configure North Bridge.
 *
 *  SDRAM configuration is conservative since we do not know the bus
 *  frequency yet. However, after this function has been called, 
 *  a memory test can be performed. Later, when we know the bus
 *  frequency, the SDRAM configuration may be optimised.	
 *
 *  Parameters :
 *  ------------
 *
 *  k0 = Platform ID
 *
 *  Return values :
 *  ---------------
 *
 *  v0 = error code (0 = no error)
 *  v1 = RAM size in bytes
 *
 ************************************************************************/
LEAF(sys_init_atlas_malta)			

	.set noreorder

#define PCIMEM_DEFAULT	    s0
#define RA		    gp
#define MEMSIZE		    sp

	move		    RA, ra

	DISP_PLATFORM

	/* Get default base address for PCI memory access */
	jal	sys_core_get_pcimem_base
	nop
	move    PCIMEM_DEFAULT, v0

        /* For Malta we skip setup of SAA9730, since it is Atlas specific */ 	
	li	t0, PRODUCT_MALTA_ID
	beq	t0, k0, setup_sdram
	nop

	/* Setup SAA9730 memory mapping */
	li	a0, ATLAS_DEVNUM_SAA9730
	li	a1, PCI_CFG_BASE1
	move	a2, PCIMEM_DEFAULT
	li	a3, KSEG1(ATLAS_CORECTRL_BASE)
	jal	sys_core_config_write
	nop
	bne	v0, zero, error_init
	nop

	/*  Enable SAA9730 memory space
	 *  (read/modify/write PCI Command register).
	 */
	li	a0, ATLAS_DEVNUM_SAA9730
	li	a1, PCI_SC
	li	a2, KSEG1(ATLAS_CORECTRL_BASE)
	jal	sys_core_config_read
	nop
	bne	v0, zero, error_init
	nop
	li	t0, PCI_SC_CMD_MS_BIT | PCI_SC_CMD_SERR_BIT
	or	a2, v1, t0
	li	a0, ATLAS_DEVNUM_SAA9730
	li	a1, PCI_SC
	li	a3, KSEG1(ATLAS_CORECTRL_BASE)
	jal	sys_core_config_write
	nop
	bne	v0, zero, error_init
	nop

        /* Init I2C controller in SAA9730 (run as slow as possible) */
	li	t0, SAA9730_I2CSC_I2CCC_6400 << SAA9730_I2CSC_I2CCC_SHF
	/* Base address of SAA9730 */
	KSEG1A( PCIMEM_DEFAULT )
	sw	t0, SAA9730_I2CSC_OFS( PCIMEM_DEFAULT )

setup_sdram:
		
	/* Get max SDRAM module bank size */
	jal	sys_core_get_max_sdram_bank
	nop
	move	a1, v0
	
	/* Determine SDRAM parameters */
	li      a0, ATLAS_SYSTEMRAM_SIZE
	jal     sys_determine_sdram_parms
	nop
	bne	v0, zero, error_init
	nop
	addu	MEMSIZE, t1, t2

	/* Configure North Bridge SDRAM parameters */
	li      a0, ATLAS_CPUFREQ_LOWEST_MHZ
	move	a1, v1
	move	a2, t0
	move	a3, t1
	move	t0, t2
	li	t1, KSEG1(ATLAS_CORECTRL_BASE)
	jal	sys_core_configure_sdram
	nop
	bne	v0, zero, error_init
	nop

	/* Configure North Bridge memory map */
	li      a0, ATLAS_PCIMEM1_BASE
	li	a1, ATLAS_PCIMEM1_SIZE + ATLAS_PCIMEM2_SIZE
	li	a2, ATLAS_PCIMEM3_BASE
	li	a3, ATLAS_PCIMEM3_SIZE
	li	t0, ATLAS_SYSTEMFLASH_BASE
	li	t1, ATLAS_SYSTEMFLASH_SIZE + ATLAS_MONITORFLASH_SIZE
	li	t2, KSEG1(ATLAS_CORECTRL_BASE)
	jal	sys_core_setup_decode
	nop
	bne	v0, zero, error_init
	nop

	/*  If Malta, remap PCI I/O.
	 *  We need to do this since the PIIX4 device on Malta requires
	 *  IO mapping to start at 0.
	 */

        /* For Malta we skip setup of SAA9730, since it is Atlas specific */ 	
	li	t0, PRODUCT_MALTA_ID
	bne	t0, k0, 1f
	nop
	li	a0, KSEG1(ATLAS_CORECTRL_BASE)
	jal     sys_core_remap_pci_io
	nop
1:
				
	/* Setup return parameters */
        move    v0, zero
	move	v1, MEMSIZE

error_init:

        jr      RA
	nop

#undef PCIMEM_DEFAULT
#undef RA
#undef MEMSIZE
				
END(sys_init_atlas_malta)		

		
/************************************************************************	
 *
 *                          sys_spd_read
 *  Description :
 *  -------------
 *
 *  Function for reading data byte from SPD (or other serial EEPROM device).
 *
 *  Parameters :
 *  ------------
 *
 *  a0 = sub-address
 *  k0 = Platform ID
 *
 *  Return values :
 *  ---------------
 *
 *  v0 = error code (0 if OK)
 *  v1 = byte read
 *
 ************************************************************************/
LEAF(sys_spd_read)

#define SPD_ADDR	t0
#define SUB_ADDR	t1
#define RA		t2

	move	RA,   ra

	DISP_STR( msg_spd )
	
	/* Setup SPD address and sub-address */	
	li	SPD_ADDR,  (CORE_EEPROM_IICADR_SPD000 << 1)
	move	SUB_ADDR,  a0

	/* Branch on platform */
	li	t3, PRODUCT_ATLASA_ID
	beq	t3, k0, eeprom_atlas
	nop

	/* Malta */

eeprom_malta:
	
	/*  Set I2C registers in FPGA to a well-defined state (not
	 *  really necessary).
	 *  Macros use t7..t6.
	 */
	I2C_FPGA_ENABLE

	jal     iic_malta_start
	nop

	ori	a0, SPD_ADDR, I2C_WRITE_BIT    /* SPD address + write bit */
	jal	iic_malta_write
	nop
	li	a0, I2C_ACK_BIT
	bne	v0, a0, error_eeprom
	li	v0, ERROR_SPD

	move	a0, SUB_ADDR		       /* Subaddress		  */
	jal	iic_malta_write
	nop
	li	a0, I2C_ACK_BIT
	bne	v0, a0, error_eeprom
	li	v0, ERROR_SPD
	
	jal	iic_malta_start
	nop

	ori     a0, SPD_ADDR, I2C_READ_BIT     /* SPD address + read bit */
	jal     iic_malta_write
	nop
	li	a0, I2C_ACK_BIT
	bne	v0, a0, error_eeprom
	li	v0, ERROR_SPD

	/* Read data */
	jal	iic_malta_read		       /* Returns data in v0     */
	nop
	move	v1, v0

	jal	iic_malta_stop
	nop

	b	eeprom_done
	nop

iic_malta_start :

	I2C_DIRECTION( SCL_TX, SDA_TX )
	
	I2C_TX( SCL_HI, SDA_HI )	
	I2C_TX( SCL_HI, SDA_LO )	/* Hi to Lo transition -> START */
	I2C_TX( SCL_LO, SDA_LO )

	jr	ra
	nop

iic_malta_write :

	/*  a0 =  byte to write
	 *  v0 := ACK/NACK bit
	 */

	I2C_DIRECTION( SCL_TX, SDA_TX )

	li	t3, 7		      /* 8 bit loop counter */
1:
	/* Determine data[t3] (MSb to be transmitted first) */
	srlv	t4, a0, t3
	andi	t4, 1
	beq	t4, zero, 2f
	nop

	I2C_TX( SCL_LO, SDA_HI )	/* Set SDA	    */
	I2C_TX( SCL_HI, SDA_HI )	/* Clock Hi	    */
	I2C_TX( SCL_LO, SDA_HI )	/* Clock Lo	    */
	b	3f
	nop
2:
	I2C_TX( SCL_LO, SDA_LO )	/* Clear SDA	    */
	I2C_TX( SCL_HI, SDA_LO )	/* Clock Hi	    */
	I2C_TX( SCL_LO, SDA_LO )	/* Clock lo	    */

3:
	bne	t3, zero, 1b
	addiu	t3, -1

	/*  Get acknowledge. 
	 *
	 *  Note : Between the time that clock was driven low (see above)
	 *         and the direction of SDA is changed (see below),
	 *         there may be a conflict where both the I2C master and
	 *         the I2C slave are driving SDA. Hardware allows for
	 *         this (open drain implementation).
	 */

	I2C_DIRECTION( SCL_TX, SDA_RX )

	I2C_TX( SCL_HI, SDA_HI )	/* Clock Hi, dummy SDA */
	I2C_RX( v0 )			/* Read SDA	       */
	I2C_TX( SCL_LO, SDA_HI )	/* Clock Lo, dummy SDA */

	jr      ra
	nop

iic_malta_read :

	/* v0 := data read */

	I2C_DIRECTION( SCL_TX, SDA_RX )

	move	v0, zero	        /* Init result register */
	li	t3, 8			/* 8 bit loop counter   */
1:
	sll	v0, 1

	I2C_TX( SCL_HI, SDA_HI )	/* Clock Hi, dummy SDA	*/
	I2C_RX( t4 )			/* Read SDA		*/
	I2C_TX( SCL_LO, SDA_HI )	/* Clock Lo, dummy SDA	*/

	addiu	t3, -1
	bne	t3, zero, 1b
	or	v0, t4

	/* Generate NACK */

	I2C_TX( SCL_LO, I2C_NACK_BIT )
	I2C_DIRECTION( SCL_TX, SDA_TX )
	I2C_TX( SCL_HI, I2C_NACK_BIT )
	I2C_TX( SCL_LO, I2C_NACK_BIT )

	jr	ra
	nop

iic_malta_stop :

	I2C_DIRECTION( SCL_TX, SDA_TX )
	
	I2C_TX( SCL_LO, SDA_LO )	
	I2C_TX( SCL_HI, SDA_LO )	/* Lo to Hi transition -> STOP */
	I2C_TX( SCL_HI, SDA_HI )
	I2C_TX( SCL_LO, SDA_HI )

	jr	ra
	nop

	/* ATLAS */

eeprom_atlas:

	/* Write EEPROM address, sub-address, EEPROM address */

	/* Byte1 : Sub-address */
	sll	a0, SUB_ADDR, SAA9730_I2CTFR_BYTE1_SHF
	ori	a0, SAA9730_I2CTFR_ATTR_CONT << SAA9730_I2CTFR_BYTE1ATTR_SHF
	
	/* Byte2 : EEPROM address */
	ori	t3, SPD_ADDR, I2C_WRITE_BIT		/* Last bit indicates write */
	sll	t3, SAA9730_I2CTFR_BYTE2_SHF
	ori	t3, t3, SAA9730_I2CTFR_ATTR_START << SAA9730_I2CTFR_BYTE2ATTR_SHF
	or	a0, t3
	
	/* Byte0 : EEPROM address again */
	ori	t3, SPD_ADDR, I2C_READ_BIT
	sll	t3, SAA9730_I2CTFR_BYTE0_SHF
	ori	t3, t3, SAA9730_I2CTFR_ATTR_START << SAA9730_I2CTFR_BYTE0ATTR_SHF
	or	a0, t3

	/*  Get default base address for PCI memory access, which is the
	 *  also the address used for the SAA9730 device.
	 */
	jal	sys_core_get_pcimem_base
	nop
	move	a1, v0
	KSEG1A( a1 )
	
	/* Perform operation */
	jal	i2c_atlas
	nop	
	
	/* Read byte */

	/* Byte2 : data will be read hereto */
	li	a0, SAA9730_I2CTFR_ATTR_STOP << SAA9730_I2CTFR_BYTE2ATTR_SHF
	
	/* Perform operation */
	jal	i2c_atlas
	nop

	/*  Byte2 now contains the data read. Read it and shift it, 
	 *  placing the result in v1.
	 */

	lw	v1, SAA9730_I2CTFR_OFS(a1)
	and	v1, SAA9730_I2CTFR_BYTE2_MSK
	srl	v1, SAA9730_I2CTFR_BYTE2_SHF

	b	eeprom_done
	nop

i2c_atlas :	

	/* a0 = data, a1 = base address of SAA9730 */

	/* Request write operation */
	sw	a0, SAA9730_I2CTFR_OFS(a1)

	/* Poll Busy flag */
	li	a0, SAA9730_I2CTFR_BUSY_MSK	
1:		
	lw	t3, SAA9730_I2CTFR_OFS(a1)
	and	t3, a0
	bne	t3, zero, 1b
	nop

	/* Check error flag */
	li      a0, SAA9730_I2CTFR_ERR_MSK
	lw	t3, SAA9730_I2CTFR_OFS(a1)
	and	t3, a0
	bne	t3, zero, error_eeprom
	li	v0, ERROR_SPD

	jr	ra
	nop

	/* Done */

eeprom_done:

	move	v0, zero
	
error_eeprom:

	DISP_PLATFORM

	jr	RA
	nop
	
END(sys_spd_read)


	
	.text

/* Messages */

       .text
	
MSG( msg_atlas,	"ATLAS" )
MSG( msg_malta, "MALTA" )
MSG( msg_spd,   "SPD"   )

⌨️ 快捷键说明

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