📄 asm_init.s
字号:
/* * (C) Copyright 2004-05; Tundra Semiconductor Corp. * * Added automatic detect of SDC settings * Copyright (c) 2005 Freescale Semiconductor, Inc. * Maintainer tie-fei.zang@freescale.com * * 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 *//* * FILENAME: asm_init.s * * Originator: Alex Bounine * * DESCRIPTION: * Initialization code for the Tundra Tsi108 bridge chip * */#include <config.h>#include <version.h>#include <ppc_asm.tmpl>#include <ppc_defs.h>#include <asm/processor.h>#include <tsi108.h>/* * Build Configuration Options *//* #define DISABLE_PBM disables usage of PB Master *//* #define SDC_HARDCODED_INIT config SDRAM controller with hardcoded values *//* #define SDC_AUTOPRECH_EN enable SDRAM auto precharge *//* * Hardcoded SDC settings */#ifdef SDC_HARDCODED_INIT/* Micron MT9HTF6472AY-40EA1 : Unbuffered, 512MB, 400, CL3, Single Rank */#define VAL_SD_REFRESH (0x61A)#define VAL_SD_TIMING (0x0308336b)#define VAL_SD_D0_CTRL (0x07100021) /* auto-precharge disabled */#define VAL_SD_D0_BAR (0x0FE00000) /* 512MB @ 0x00000000 */#define VAL_SD_D1_CTRL (0x07100021) /* auto-precharge disabled */#define VAL_SD_D1_BAR (0x0FE00200) /* 512MB @ 0x20000000 */#endif /* SDC_HARDCODED_INIT *//* CPU Configuration: CPU Address and Data Parity enables.#define CPU_AP#define CPU_DP*//* * Macros * !!! Attention !!! Macros LOAD_PTR, LOAD_U32 and LOAD_MEM defined below are * expected to work correctly for the CSR space within 32KB range. * * LOAD_PTR and LOAD_U32 - load specified register with a 32 bit constant. * These macros are absolutely identical except their names. This difference * is provided intentionally for better readable code. */#define LOAD_PTR(reg,const32) \ addis reg,r0,const32@h; ori reg,reg,const32@l#define LOAD_U32(reg,const32) \ addis reg,r0,const32@h; ori reg,reg,const32@l/* LOADMEM initializes a register with the contents of a specified 32-bit * memory location, usually a CSR value. */#define LOAD_MEM(reg,addr32) \ addis reg,r0,addr32@ha; lwz reg,addr32@l(reg)#ifndef SDC_HARDCODED_INITsdc_clk_sync: /* MHz: 0,0,183,100,133,167,200,233 */ .long 0, 0, 6, 10, 8, 6, 5, 4 /* nSec */#endif/* * board_asm_init() - early initialization function. Coded to be portable to * dual-CPU configuration. * Checks CPU number and performs board HW initialization if called for CPU0. * Registers used: r3,r4,r5,r6,r19,r29 * * NOTE: For dual-CPU configuration only CPU0 is allowed to configure Tsi108 * and the rest of the board. Current implementation demonstrates two * possible ways to identify CPU number: * - for MPC74xx platform: uses MSSCR0[ID] bit as defined in UM. * - for PPC750FX/GX boards: uses WHO_AM_I bit reported by Tsi108. */ .globl board_asm_initboard_asm_init: mflr r19 /* Save LR to be able return later. */ bl icache_enable /* Enable icache to reduce reads from flash. *//* Initialize pointer to Tsi108 register space */ LOAD_PTR(r29,CFG_TSI108_CSR_RST_BASE)/* r29 - pointer to tsi108 CSR space */ ori r4,r29,TSI108_PB_REG_OFFSET/* Check Processor Version Number */ mfspr r3, PVR rlwinm r3,r3,16,16,23 /* get ((Processor Version Number) & 0xFF00) */ cmpli 0,0,r3,0x8000 /* MPC74xx */ bne cont_brd_init /* * For MPC744x/5x enable extended BATs[4-7] * Sri: Set HIGH_BAT_EN and XBSEN, and SPD =1 * to disable prefetch */ mfspr r5, HID0 oris r5, r5, 0x0080 /* Set HID0[HIGH_BAT_EN] bit #8 */ ori r5, r5, 0x0380 /* Set SPD,XBSEN,SGE bits #22,23,24 */ mtspr HID0, r5 isync sync /* Adding code to disable external interventions in MPX bus mode */ mfspr r3, 1014 oris r3, r3, 0x0100 /* Set the EIDIS bit in MSSCR0: bit 7 */ mtspr 1014, r3 isync sync /* Sri: code to enable FP unit */ mfmsr r3 ori r3, r3, 0x2000 mtmsr r3 isync sync /* def CONFIG_DUAL_CPU * For MPC74xx processor, use MSSCR0[ID] bit to identify CPU number. */#if(1) mfspr r3,1014 /* read MSSCR0 */ rlwinm. r3,r3,27,31,31 /* get processor ID number */ mtspr SPRN_PIR,r3 /* Save CPU ID */ sync bne init_done b do_tsi108_initcont_brd_init: /* An alternative method of checking the processor number (in addition * to configuration using MSSCR0[ID] bit on MPC74xx). * Good for IBM PPC750FX/GX. */ lwz r3,PB_BUS_MS_SELECT(r4) /* read PB_ID register */ rlwinm. r3,r3,24,31,31 /* get processor ID number */ bne init_done#elsecont_brd_init:#endif /* CONFIG_DUAL_CPU */ /* Initialize Tsi108 chip */do_tsi108_init: /* * Adjust HLP/Flash parameters. By default after reset the HLP port is * set to support slow devices. Better performance can be achived when * an optimal parameters are used for specific EPROM device. * NOTE: This should be performed ASAP for the emulation platform * because it has 5MHz HLP clocking. */#ifdef CONFIG_TSI108EMU ori r4,r29,TSI108_HLP_REG_OFFSET LOAD_U32(r5,0x434422c0) stw r5,0x08(r4) /* set HLP B0_CTRL0 */ sync LOAD_U32(r5,0xd0012000) stw r5,0x0c(r4) /* set HLP B0_CTRL1 */ sync#endif /* Initialize PB interface. */ ori r4,r29,TSI108_PB_REG_OFFSET#if (CFG_TSI108_CSR_BASE != CFG_TSI108_CSR_RST_BASE) /* Relocate (if required) Tsi108 registers. Set new value for * PB_REG_BAR: * Note we are in the 32-bit address mode. */ LOAD_U32(r5,(CFG_TSI108_CSR_BASE | 0x01)) /* PB_REG_BAR: BA + EN */ stw r5,PB_REG_BAR(r4) andis. r29,r5,0xFFFF sync ori r4,r29,TSI108_PB_REG_OFFSET#endif /* Set PB Slave configuration register */ LOAD_U32(r5,0x00002481) /* PB_SCR: TEA enabled,AACK delay = 1 */ lwz r3, PB_RSR(r4) /* get PB bus mode */ xori r3,r3,0x0001 /* mask PB_BMODE: r3 -> (0 = 60X, 1 = MPX) */ rlwimi r5,r3,14,17,17 /* for MPX: set DTI_MODE bit */ stw r5,PB_SCR(r4) sync /* Configure PB Arbiter */ lwz r5,PB_ARB_CTRL(r4) /* Read PB Arbiter Control Register */ li r3, 0x00F0 /* ARB_PIPELINE_DEP mask */#ifdef DISABLE_PBM ori r3,r3,0x1000 /* add PBM_EN to clear (enabled by default) */#endif andc r5,r5,r3 /* Clear the masked bit fields */ ori r5,r5,0x0001 /* Set pipeline depth */ stw r5,PB_ARB_CTRL(r4)#if (0) /* currently using the default settings for PBM after reset */ LOAD_U32(r5,0x) /* value for PB_MCR */ stw r5,PB_MCR(r4) sync LOAD_U32(r5,0x) /* value for PB_MCMD */ stw r5,PB_MCMD(r4) sync#endif /* Disable or enable PVT based on processor bus frequency * 1. Read CG_PWRUP_STATUS register field bits 18,17,16 * 2. See if the value is < or > 133mhz (18:16 = 100) * 3. If > enable PVT */ LOAD_U32(r3,0xC0002234) lwz r3,0(r3) rlwinm r3,r3,16,29,31 cmpi 0,0,r3,0x0004 bgt sdc_init#ifndef CONFIG_TSI108EMU /* FIXME: Disable PB calibration control for any real Tsi108 board */ li r5,0x0101 /* disable calibration control */ stw r5,PB_PVT_CTRL2(r4) sync#endif /* Initialize SDRAM controller. */sdc_init:#ifndef SDC_HARDCODED_INIT /* get SDC clock prior doing sdram controller autoconfig */ ori r4,r29,TSI108_CLK_REG_OFFSET /* r4 - ptr to CG registers */ lwz r3, CG_PWRUP_STATUS(r4) /* get CG configuration */ rlwinm r3,r3,12,29,31 /* r3 - SD clk */ lis r5,sdc_clk_sync@h ori r5,r5,sdc_clk_sync@l /* Sri: At this point check if r3 = 001. If yes, * the memory frequency should be same as the * MPX bus frequency */ cmpi 0,0,r3,0x0001 bne get_nsec lwz r6, CG_PWRUP_STATUS(r4) rlwinm r6,r6,16,29,31 mr r3,r6get_nsec: rlwinm r3,r3,2,0,31 lwzx r9,r5,r3 /* get SD clk rate in nSec */ /* ATTN: r9 will be used by SPD routine */#endif /* !SDC_HARDCODED_INIT */ ori r4,r29,TSI108_SD_REG_OFFSET /* r4 - ptr to SDRAM registers */ /* Initialize SDRAM controller. SDRAM Size = 512MB, One DIMM. */ LOAD_U32(r5,0x00) stw r5,SD_INT_ENABLE(r4) /* Ensure that interrupts are disabled */#ifdef ENABLE_SDRAM_ECC li r5, 0x01#endif /* ENABLE_SDRAM_ECC */ stw r5,SD_ECC_CTRL(r4) /* Enable/Disable ECC */ sync#ifdef SDC_HARDCODED_INIT /* config sdram controller with hardcoded values */ /* First read the CG_PWRUP_STATUS register to get the * memory speed from bits 22,21,20 */ LOAD_U32(r3,0xC0002234) lwz r3,0(r3) rlwinm r3,r3,12,29,31 /* Now first check for 166, then 200, or default */ cmpi 0,0,r3,0x0005 bne check_for_200mhz /* set values for 166 Mhz memory speed * Set refresh rate and timing parameters */ LOAD_U32(r5,0x00000515) stw r5,SD_REFRESH(r4) LOAD_U32(r5,0x03073368) stw r5,SD_TIMING(r4) sync /* Initialize DIMM0 control and BAR registers */ LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */#ifdef SDC_AUTOPRECH_EN oris r5,r5,0x0001 /* set auto precharge EN bit */#endif stw r5,SD_D0_CTRL(r4) LOAD_U32(r5,VAL_SD_D0_BAR) stw r5,SD_D0_BAR(r4) sync /* Initialize DIMM1 control and BAR registers * (same as dimm 0, next 512MB, disabled) */ LOAD_U32(r5,VAL_SD_D1_CTRL) /* auto-precharge disabled */#ifdef SDC_AUTOPRECH_EN oris r5,r5,0x0001 /* set auto precharge EN bit */#endif stw r5,SD_D1_CTRL(r4) LOAD_U32(r5,VAL_SD_D1_BAR) stw r5,SD_D1_BAR(r4) sync b sdc_init_donecheck_for_200mhz: cmpi 0,0,r3,0x0006 bne set_default_values /* set values for 200Mhz memory speed * Set refresh rate and timing parameters */ LOAD_U32(r5,0x0000061a) stw r5,SD_REFRESH(r4) LOAD_U32(r5,0x03083348) stw r5,SD_TIMING(r4) sync /* Initialize DIMM0 control and BAR registers */ LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */#ifdef SDC_AUTOPRECH_EN oris r5,r5,0x0001 /* set auto precharge EN bit */#endif stw r5,SD_D0_CTRL(r4) LOAD_U32(r5,VAL_SD_D0_BAR) stw r5,SD_D0_BAR(r4) sync /* Initialize DIMM1 control and BAR registers * (same as dimm 0, next 512MB, disabled) */ LOAD_U32(r5,VAL_SD_D1_CTRL) /* auto-precharge disabled */#ifdef SDC_AUTOPRECH_EN oris r5,r5,0x0001 /* set auto precharge EN bit */#endif stw r5,SD_D1_CTRL(r4) LOAD_U32(r5,VAL_SD_D1_BAR) stw r5,SD_D1_BAR(r4) sync b sdc_init_doneset_default_values: /* Set refresh rate and timing parameters */ LOAD_U32(r5,VAL_SD_REFRESH) stw r5,SD_REFRESH(r4) LOAD_U32(r5,VAL_SD_TIMING) stw r5,SD_TIMING(r4) sync /* Initialize DIMM0 control and BAR registers */ LOAD_U32(r5,VAL_SD_D0_CTRL) /* auto-precharge disabled */#ifdef SDC_AUTOPRECH_EN oris r5,r5,0x0001 /* set auto precharge EN bit */#endif stw r5,SD_D0_CTRL(r4) LOAD_U32(r5,VAL_SD_D0_BAR) stw r5,SD_D0_BAR(r4) sync /* Initialize DIMM1 control and BAR registers * (same as dimm 0, next 512MB, disabled) */ LOAD_U32(r5,VAL_SD_D1_CTRL) /* auto-precharge disabled */#ifdef SDC_AUTOPRECH_EN oris r5,r5,0x0001 /* set auto precharge EN bit */#endif stw r5,SD_D1_CTRL(r4) LOAD_U32(r5,VAL_SD_D1_BAR) stw r5,SD_D1_BAR(r4) sync#else /* !SDC_HARDCODED_INIT */ bl tsi108_sdram_spd /* automatically detect SDC settings */#endif /* SDC_HARDCODED_INIT */sdc_init_done:#ifdef DISABLE_PBM LOAD_U32(r5,0x00000030) /* PB_EN + OCN_EN */#else LOAD_U32(r5,0x00000230) /* PB_EN + OCN_EN + PB/OCN=80/20 */#endif /* DISABLE_PBM */#ifdef CONFIG_TSI108EMU oris r5,r5,0x0010 /* set EMULATION_MODE bit */#endif stw r5,SD_CTRL(r4) eieio sync /* Enable SDRAM access */ oris r5,r5,0x8000 /* start SDC: set SD_CTRL[ENABLE] bit */ stw r5,SD_CTRL(r4) syncwait_init_complete:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -