📄 gt64120_core.s
字号:
/************************************************************************ * * gt64120_core.S * * Galileo specific functions * * ###################################################################### * * mips_start_of_legal_notice * * Copyright (c) 2004 MIPS Technologies, Inc. All rights reserved. * * * Unpublished rights (if any) reserved under the copyright laws of the * United States of America and other countries. * * This code is proprietary to MIPS Technologies, Inc. ("MIPS * Technologies"). Any copying, reproducing, modifying or use of this code * (in whole or in part) that is not expressly permitted in writing by MIPS * Technologies or an authorized third party is strictly prohibited. At a * minimum, this code is protected under unfair competition and copyright * laws. Violations thereof may result in criminal penalties and fines. * * MIPS Technologies reserves the right to change this code to improve * function, design or otherwise. MIPS Technologies does not assume any * liability arising out of the application or use of this code, or of any * error or omission in such code. Any warranties, whether express, * statutory, implied or otherwise, including but not limited to the implied * warranties of merchantability or fitness for a particular purpose, are * excluded. Except as expressly provided in any written license agreement * from MIPS Technologies or an authorized third party, the furnishing of * this code does not give recipient any license to any intellectual * property rights, including any patent rights, that cover this code. * * This code shall not be exported, reexported, transferred, or released, * directly or indirectly, in violation of the law of any country or * international law, regulation, treaty, Executive Order, statute, * amendments or supplements thereto. Should a conflict arise regarding the * export, reexport, transfer, or release of this code, the laws of the * United States of America shall be the governing law. * * This code constitutes one or more of the following: commercial computer * software, commercial computer software documentation or other commercial * items. If the user of this code, 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 code, 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 code 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 code from MIPS Technologies or an authorized * third party. * * * * * mips_end_of_legal_notice * * ************************************************************************//************************************************************************ * Include files ************************************************************************/ #include <sysdefs.h>#include <mips.h>#include <init.h>#include <spd.h>#include <pci_api.h>#include <pci.h>#include <gt64120.h>/************************************************************************ * Definitions ************************************************************************/ /* Parameters for setup_cpu_decode/setup_cpu_decode */#define LO a0#define HI a1#define REGLO a2#define REGHI a3/************************************************************************ * Public variables ************************************************************************//************************************************************************ * Static variables ************************************************************************//************************************************************************ * Implementation : Public functions ************************************************************************/ .set noreorder/************************************************************************ * * gt64120_write_reg * Description : * ------------- * Write data to GT64120 register. * * Note : * ------ * This routine is called only via sys_func_noram() in module sys.c * and must obey c calling conventions. * * Parameters : * ------------ * a0 = address of register * a1 = data to be written * * Return values : * --------------- * 0 * ************************************************************************/LEAF(gt64120_write_reg) /* Flush all RAM accesses */ sync lw t0, KSEG1(0) move zero, t0 /* Perform the write */ GT_SW( a1, 0, a0 ) /* Done */ jr ra move v0, zeroEND(gt64120_write_reg) /************************************************************************ * access_gt64120 * Common function calling conventions, see init_core.S ************************************************************************/LEAF(access_gt64120) li t8, FUNC_INIT beq t9, t8, gt64120_init nop li t8, FUNC_GET_PCIMEM_BASE beq t9, t8, gt64120_get_pcimem_base nop li t8, FUNC_CONFIG_WRITE beq t9, t8, gt64120_config_write nop li t8, FUNC_CONFIGURE_SDRAM beq t9, t8, gt64120_configure_sdram nop li t8, FUNC_SETUP_DECODE beq t9, t8, gt64120_setup_decode nop /* FUNC_REMAP_PCI_IO */ j gt64120_remap_pci_io nopEND(access_gt64120)/************************************************************************ * Implementation : Static functions ************************************************************************//************************************************************************ * * gt64120_init * Description : * ------------- * * Initialise GT64120 just enough so that we can access PCI. * * Parameters : * ------------ * * a0 = Base address to be used for access to North Bridge registers. * * Return values : * --------------- * * v0 = error code (0 = OK) * v1 = 1 -> Request software reset * ************************************************************************/SLEAF(gt64120_init) /* Default return values */ move v0, zero move v1, zero /* We need to determine if we arrived here due to either : * * 1) A hardware or software reset. * 2) Due to a "go bfc00000" command or under EJTAG control. * * In case 2, we issue a software reset. We need to do * this since some devices will not otherwise be properly * reset. * * We detect case 2 by checking if the GT64120 * "Internal Space Decode" register is accessible at the * default address. This is the case after a hardware or * software reset, but is NOT otherwise the case since * the mapping of the system controller is changed below. */ li t0, KSEG1(GT_DEF_BASE) /* Base address after a reset */ GT_LW( t1, GT_ISD_OFS, t0 ) li t2, GT_ISD_DEFAULT beq t1, t2, 1f nop /* Request software reset */ li v1, 1 jr ra nop1: /* Setup where we want the Galileo registers to be addressed */ srl t1, a0, 21 GT_SW( t1, GT_ISD_OFS, t0 ) move t0, a0 KSEG1A(t0) /* Setup GT64120 CPU interface */ GT_LW( t1, GT_CPU_OFS, t0 ) li t2, ~GT_CPU_WR_MSK and t1, t2 li t2, GT_CPU_WR_DDDD << GT_CPU_WR_SHF or t1, t2 GT_SW( t1, GT_CPU_OFS, t0 ) /* HW bug workaround: Extend BootCS mapping area to access FPGA without * 4 x access on CBUS per 1 x access from SysAD. */ li t1, 0 GT_SW( t1, GT_CS3HD_OFS, t0 ) li t1, 0xf0 GT_SW( t1, GT_BOOTLD_OFS, t0 ) li t1, 0xff GT_SW( t1, GT_BOOTHD_OFS, t0 ) /* Setup byte/word swap */#ifdef EB li t1, 0x00401#else li t1, 0x10001#endif GT_SW( t1, GT_PCI0_CMD_OFS, t0 ) /* Change retrycount to a value, which is not 0 */ li t1, 0x00ffffff GT_SW( t1, GT_PCI0_TOR_OFS, t0 ) /* Setup GT64120 to have Master capability */ li t1, GT_CFGADDR_CFGEN_BIT |\ (PCI_BUS_LOCAL << GT_CFGADDR_BUSNUM_SHF) |\ (GT_DEV << GT_CFGADDR_DEVNUM_SHF) |\ (0 << GT_CFGADDR_FUNCNUM_SHF) |\ ((PCI_SC >>2) << GT_CFGADDR_REGNUM_SHF) GT_SW( t1, GT_PCI0_CFGADDR_OFS, t0 ) GT_LW( t2, GT_PCI0_CFGDATA_OFS, t0 ) li t1, (PCI_SC_CMD_MS_BIT | PCI_SC_CMD_BM_BIT | \ PCI_SC_CMD_PERR_BIT | PCI_SC_CMD_SERR_BIT ) or t2, t1 li t1, GT_CFGADDR_CFGEN_BIT |\ (PCI_BUS_LOCAL << GT_CFGADDR_BUSNUM_SHF) |\ (GT_DEV << GT_CFGADDR_DEVNUM_SHF) |\ (0 << GT_CFGADDR_FUNCNUM_SHF) |\ ((PCI_SC >> 2) << GT_CFGADDR_REGNUM_SHF) GT_SW( t1, GT_PCI0_CFGADDR_OFS, t0 ) GT_SW( t2, GT_PCI0_CFGDATA_OFS, t0 ) /* Setup GT64120 PCI latency timer */ li t1, GT_CFGADDR_CFGEN_BIT |\ (PCI_BUS_LOCAL << GT_CFGADDR_BUSNUM_SHF) |\ (GT_DEV << GT_CFGADDR_DEVNUM_SHF) |\ (0 << GT_CFGADDR_FUNCNUM_SHF) |\ ((PCI_BHLC >> 2) << GT_CFGADDR_REGNUM_SHF) GT_SW( t1, GT_PCI0_CFGADDR_OFS, t0 ) GT_LW( t2, GT_PCI0_CFGDATA_OFS, t0 ) li t1, (GT_LATTIM_MIN << PCI_BHLC_LT_SHF) or t2, t1 li t1, GT_CFGADDR_CFGEN_BIT |\ (PCI_BUS_LOCAL << GT_CFGADDR_BUSNUM_SHF) |\ (GT_DEV << GT_CFGADDR_DEVNUM_SHF) |\ (0 << GT_CFGADDR_FUNCNUM_SHF) |\ ((PCI_BHLC >> 2) << GT_CFGADDR_REGNUM_SHF) GT_SW( t1, GT_PCI0_CFGADDR_OFS, t0 ) GT_SW( t2, GT_PCI0_CFGDATA_OFS, t0 ) jr ra nop END(gt64120_init)/************************************************************************ * * gt64120_get_pcimem_base * Description : * ------------- * * Return base address for PCI memory cycles. * * Parameters : * ------------ * * None * * Return values : * --------------- * * v0 = Base address for PCI memory cycles * ************************************************************************/SLEAF(gt64120_get_pcimem_base) li v0, GT_DEF_PCI0_MEM0_BASE jr ra nopEND(gt64120_get_pcimem_base)/************************************************************************ * * gt64120_config_write * Description : * ------------- * * Perform 32 bit PCI configuration write cycle on local bus. * * Parameters : * ------------ * * a0 = device number (function 0 assumed) * a1 = register * a2 = data * a3 = Base address to be used for access to North Bridge registers. * * Return values : * --------------- * * v0 = 0 if OK * v0 = ERROR_NB_CONFIG_WRITE if not OK * ************************************************************************/SLEAF(gt64120_config_write) /* Clear cause register bits */ GT_SW( zero, GT_INTRCAUSE_OFS, a3 ) /* Write to requested register */ sll t0, a0, GT_CFGADDR_DEVNUM_SHF srl t1, a1, 2 sll t1, GT_CFGADDR_REGNUM_SHF or t0, t1 li t1, GT_CFGADDR_CFGEN_BIT |\ (PCI_BUS_LOCAL << GT_CFGADDR_BUSNUM_SHF) |\ (0 << GT_CFGADDR_FUNCNUM_SHF) or t0, t1 GT_SW( t0, GT_PCI0_CFGADDR_OFS, a3 ) GT_SW( a2, GT_PCI0_CFGDATA_OFS, a3 ) /* Check for master abort */ GT_LW( t0, GT_INTRCAUSE_OFS, a3 ) li t1, GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT and t0, t1 beq t0, zero, 1f move v0, zero li v0, ERROR_NB_CONFIG_WRITE1: jr ra nop END(gt64120_config_write)/************************************************************************ * * gt64120_configure_sdram * Description : * ------------- * * Setup GT64120 SDRAM configuration * * Parameters : * ------------ * * a0 = Worst case (lowest) bus freq. (MHz) for setting timing parms. * a1 = Base address to be used for access to North Bridge registers. * a2 = Max SDRAM size supported by platform. * * Banks are mapped to GT64120 ranges the following way : * * bank0 -> SCSO * bank1 -> SCS2 * * Return values : * --------------- * * v0 = error code (0 = OK) * v1 = RAM size * ************************************************************************/SLEAF(gt64120_configure_sdram)#define RA s0#define FREQ s1#define GTBASE s2#define BSIZE0 s3#define BSIZE1 s4#define RAMSIZE_MAX s5#define MOD_BANKS s6 /* s0..s6 used */ move RA, ra move FREQ, a0 move GTBASE, a1 move RAMSIZE_MAX, a2 /* Detect DIMM (if present check module width) */ li a0, SPD_MODULE_WIDTH_LO jal sys_spd_read nop bne v0, zero, error_sdram li a0, 64 bne v1, a0, error_sdram li v0, ERROR_SDRAM_WIDTH li a0, SPD_MODULE_WIDTH_HI jal sys_spd_read nop bne v0, zero, error_sdram li a0, 0 bne v1, a0, error_sdram li v0, ERROR_SDRAM_WIDTH /* Number of module banks */ li a0, SPD_MODULE_BANKS jal sys_spd_read nop bne v0, zero, error_sdram nop move MOD_BANKS, v1 /**** Determine size of bank(s) ****/ li a0, SPD_ROW_DENSITY jal sys_spd_read nop bne v0, zero, error_sdram nop /* bank 0 */ li BSIZE0, 512*1024*10241: and t0, v1, 1 << 7 bne t0, zero, 2f sll v1, 1 b 1b srl BSIZE0, 12: /* bank 1 (if available) */ li t0, 1 beq MOD_BANKS, t0, 2f /* 1 bank only */ move BSIZE1, zero and v1, 0xFF beq v1, zero, 2f move BSIZE1, BSIZE0 /* 2 symmetrical banks */ /* 2 asymmetrical banks. We assume that bank0 is largest. * (TBD : Is this a fair assumption ?) */1: srl BSIZE1, 1 and t0, v1, 1 << 7 beq t0, zero, 1b sll v1, 12:#undef MOD_BANKS /* s0..s5 used */ /* Validate SDRAM parameters. * * The following data is available : * * RAMSIZE_MAX = Max allowed RAM size. * BSIZE0 = size(bank0) (in bytes). * BSIZE1 = size(bank1) (in bytes) (if available). * * Checks performed : * * BSIZE<n> <= GT_MAX_BANKSIZE * Total memory size <= RAMSIZE_MAX */ /* Check and possibly adjust bank0 size : * BSIZE0 <= MIN(GT_MAX_BANKSIZE, RAMSIZE_MAX) */ /* Calc t0 = MIN(GT_MAX_BANKSIZE, RAMSIZE_MAX) */ li t0, GT_MAX_BANKSIZE sltu t1, t0, RAMSIZE_MAX bne t1, zero, 1f nop move t0, RAMSIZE_MAX1: /* Perform check on BSIZE0 */ sltu t1, t0, BSIZE0 beq t1, zero, 1f nop /* bank 0 too large, so adjust size */ move BSIZE0, t01: /* Check and possibly adjust bank1 size. * BSIZE1 <= MIN(GT_MAX_BANKSIZE, RAMSIZE_MAX - BSIZE0) */ /* Calc t0 = MIN(GT_MAX_BANKSIZE, RAMSIZE_MAX - BSIZE0) */ li t0, GT_MAX_BANKSIZE subu t1, RAMSIZE_MAX, BSIZE0 sltu t2, t0, t1 bne t2, zero, 1f nop move t0, t11: /* Perform check on BSIZE1 */ sltu t1, t0, BSIZE1 beq t1, zero, 1f nop /* bank 1 too large, so adjust size */ move BSIZE1, t01:#undef RAMSIZE_MAX /* s0..s4 used */ /* SDRAM Burst Mode register. * Leave all bits except "Burst Order" unchanged. */ GT_LW( t0, GT_SDRAM_BM_OFS, GTBASE ) li t1, ~GT_SDRAM_BM_ORDER_MSK and t0, t1 li t1, (GT_SDRAM_BM_ORDER_SUB << GT_SDRAM_BM_ORDER_SHF) or t0, t1 GT_SW( t0, GT_SDRAM_BM_OFS, GTBASE ) /* SDRAM Address Decode register */ li t0, GT_SDRAM_ADDRDECODE_ADDR_2 GT_SW( t0, GT_SDRAM_ADDRDECODE_OFS, GTBASE )#define ACCUM s5 /* s0..s5 used */ /* SDRAM Bank0 + Bank2 Parameters registers. * SRAS precharge and SRAS to SCAS delay are * set conservatively. They may later be optimised based * on RAM parameters and system frequency. */ li ACCUM, (GT_SDRAM_B0_BW_64 << GT_SDRAM_B0_BW_SHF) |\ (GT_SDRAM_B0_SRASPRCHG_3 << GT_SDRAM_B0_SRASPRCHG_SHF) |\ (GT_SDRAM_B0_SRAS2SCAS_3 << GT_SDRAM_B0_SRAS2SCAS_SHF) /* CAS latency field : Galileo only supports CAS latency = 2 */ li a0, SPD_CASLAT /* CAS latency field in SPD device */ jal sys_spd_read /* v1 = CAS latencies supported byte */ nop bne v0, zero, error_sdram nop and t0, v1, SPD_CASLAT_2_BIT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -