// // $Id: mpc107.s,v 1.9 2000/05/30 20:14:09 garym Exp $ // // Copyright Motorola, Inc. 1999 // ALL RIGHTS RESERVED // // You are hereby granted a copyright license to use, modify, and // distribute the SOFTWARE so long as this entire notice is retained // without alteration in any modified and/or redistributed versions, // and that such modified versions are clearly identified as such. // No licenses are granted by implication, estoppel or otherwise under // any patents or trademarks of Motorola, Inc. // // The SOFTWARE is provided on an "AS IS" basis and without warranty. // To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS // ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED // WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR // PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH // REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS // THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS. // // To the maximum extent permitted by applicable law, IN NO EVENT SHALL // MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER // (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF // BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS // INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR // INABILITY TO USE THE SOFTWARE. Motorola assumes no responsibility // for the maintenance and support of the SOFTWARE. // file: kahlua.s // // 10/08/99 -- created -- GM & My // .file "mpc107.s" /* Includes */ #include "yellowknife.h" #include "dink_asm.h" .extern config_addr .extern config_data /* Globals */ .text .align 2 .global Mpc107Init //--------------------------------------------------------------------------- // MPC107 Initialization file // // Note: This file is written so as to be easily customizable and // changeable for various configurations. Therefore it uses // a lot of "ori" instructions to enable bitfields where end- // user code might use only one load of a single constant. // Use whichever you find best. // // In addition, certain lines labelled with "DBG:" cause // registers to be read for apparently no reason -- this is // so we can see the power-up reset state of those registers // on a logic analyzer. Your code will probably not need // them (unless you believe configuration pins are not set // properly) so you can delete them. // // On entry: r3 contains MPC107 Vendor/Device ID // r5 points to the MPC107 Config Address Register // r6 points to the MPC107 Config Address Register Mpc107Init: // save Mpc107 Vendor/Device ID or r11, r3, r3 // Currently, if an MPC107 is found, we must be running on // a Sandpoint with an "Altimus" board, which has a code // of 5 (from config.h). The board type is set in sprg0, // which will be stored to the "board_type" variable after // DINK is copied form ROM to RAM. addi r3, r0, 5 // SP_107 mtspr sprg0, r3 addis r3,r0,BMC_BASE // Set PCI_CMD ori r3,r3,0x0004 li r4, 0x0006 // Set to 06 (Memory Space) stwbrx r3,0,r5 sync sthbrx r4, 0, r6 sync addis r3,r0,BMC_BASE // Set PCI_STAT ori r3,r3,0x0006 stwbrx r3,0,r5 sync li r3, 0x0002 lhbrx r4, r3, r6 // Get old PCI_STAT sync ori r4, r4, 0xffff // Writing all ones will clear all bits in sthbrx r4, r3, r6 // write the modified data to CONFIG_DATA // ===PICR1=== PROCESSOR INTERFACE CONFIGURATION // // PICR1/2 are much simpler than a MPC106 equivalent, mostly due to // the elimination of the L3 interface. // Note: you cannot just set the LE(little-endian bit); there's a // special sequence involved -- contact RISC Applications for details. addis r3,r0,BMC_BASE // Select PICR1 (A8) ori r3,r3,PROCINTCONF1 stwbrx r3,0,r5 sync lwbrx r4,0,r6 // Get old PICR1 bits lis r0,0x0011 and r4,r4,r0 // preserve RCS0/Addr Map bits. lis r0, 0xff00 // oris r0, r0, 0x0040 // burst read wait states = 1 oris r0, r0, 0x0004 // processor type = 603/750 // ori r0, r0, 0x2000 // enable LocalBusSlave ori r0, r0, 0x1000 // enable Flash write ori r0, r0, 0x0800 // enable MCP* assertion // ori r0, r0, 0x0400 // enable TEA* assertion ori r0, r0, 0x0200 // enable data bus parking ori r0, r0, 0x0080 // disable Flash write size checks // ori r0, r0, 0x0040 // enable PCI store gathering ori r0, r0, 0x0010 // enable loop-snoop ori r0, r0, 0x0008 // enable address bus parking // ori r0, r0, 0x0004 // enable speculative PCI reads or r4, r4, r0 // sets the desired bits stwbrx r4,0,r6 sync // ===PICR2=== PROCESSOR INTERFACE CONFIGURATION // addis r3,r0,BMC_BASE // Select PICR2 (AC) ori r3,r3,PROCINTCONF2 stwbrx r3,0,r5 sync // Nothing preserved. lis r0, 0x0000 // oris r0, r0, 0x2000 // No Serialize Config cycles // oris r0, r0, 0x0800 // No PCI Snoop cycles oris r0, r0, 0x0400 // FF0 is Local ROM // oris r0, r0, 0x0200 // Flash write lockout oris r0, r0, 0x0000 // snoop wt states = 0 // oris r0, r0, 0x0004 // snoop wt states = 1 // oris r0, r0, 0x0008 // snoop wt states = 2 // oris r0, r0, 0x000c // snoop wt states = 3 ori r0, r0, 0x0000 // addr. phase wt states = 0 // ori r0, r0, 0x0004 // addr. phase wt states = 1 // ori r0, r0, 0x0008 // addr. phase wt states = 2 // ori r0, r0, 0x000c // addr. phase wt states = 3 stwbrx r0,0,r6 // ===EUMBBAR=== EMBEDDED UTILITIES MEMORY BLOCK BASE ADDRESS // // EUMBBAR defines a local address for the I2C, I2O, DMA, EPIC, ATU // and other registers. // // Remember that this area must be enabled in a BAT to be accessible. addis r3,r0,BMC_BASE // Select EUMBBAR (78) ori r3,r3,0x0078 stwbrx r3,0,r5 lis r4,0xfc00 // 0xFC00_0000 stwbrx r4,0,r6 sync // ===MCCR1=== MEMORY CONTROL CONFIGURATION // // MEMGO(bit 19) cannot be set until all other bits have been set // We'll revisit MCCR1 later. addis r3,r0,BMC_BASE //! Select MCCR1 (F0) ori r3,r3,0x00F0 stwbrx r3,0,r5 sync lwbrx r7,0,r6 // Get MCCR1 bits; used w/MCCR4 lis r0,0x0040 and r7,r7,r0 // R7: =0 if 32 bits, /= 0 if 64. lis r4, 0x0000 // Rom speed @100 MHz (10ns): oris r4, r4, 0x7580 // Safe Local ROM = 11+3 clocks // oris r4, r4, 0x7380 // Fast Local ROM = 7+3 clocks // oris r4, r4, 0x0010 // Burst ROM/Flash enable // oris r4, r4, 0x0004 // Self-refresh enable // oris r4, r4, 0x0002 // EDO/FP enable (else SDRAM) // oris r4, r4, 0x0001 // Parity check // Set all banks to same type (they don't have to be) // ori r4, r4, 0xFFFF // 16Mbit/2bank SDRAM // ori r4, r4, 0x5555 // 64Mbit/2bank SDRAM ori r4, r4, 0x0000 // 64Mbit/4bank SDRAM stwbrx r4,0,r6 sync // ===MCCR2=== MEMORY CONTROL CONFIGURATION // addis r3,r0,BMC_BASE // Select MCCR2 (F4) ori r3,r3,0x00F4 stwbrx r3,0,r5 sync lis r4, 0x0000 // oris r4, r4, 0x4000 // TS_WAIT_TIMER = 3 clocks oris r4, r4, 0x0400 // ASRISE = 2 clocks oris r4, r4, 0x0040 // ASFALL = 2 clocks // oris r4, r4, 0x0010 // SDRAM Parity (else ECC) // oris r4, r4, 0x0008 // SDRAM inline writes // oris r4, r4, 0x0004 // SDRAM inline reads // oris r4, r4, 0x0002 // ECC enable // oris r4, r4, 0x0001 // EDO (else FP) // Select a refresh rate; it needs to match the bus speed; if too // slow, data may be lost; if too fast, performance is lost. We // use the fastest value so we run at all speeds. // Refresh = (15600ns/busclk) - (213 (see UM)). // ori r4, r4, 0x1d2c // 133 MHz mem bus = 1867 // ori r4, r4, 0x150c // 100 MHz mem bus = 1347 // ori r4, r4, 0x10fc // 83 MHz mem bus = 1087 // ori r4, r4, 0x0cc4 // 66 MHz mem bus = 817 ori r4, r4, 0x04cc // 33 MHz mem bus (SAFE) = 307 // ori r4, r4, 0x0002 // Reserve a page // ori r4, r4, 0x0001 // RWM parity stwbrx r4,0,r6 sync // ===MCCR3=== MEMORY CONTROL CONFIGURATION // addis r3,r0,BMC_BASE // Select MCCR3 (F8) ori r3,r3,0x00F8 stwbrx r3,0,r5 sync lis r4, 0x7000 // BSTOPRE_M = 7 (see A/N) oris r4, r4, 0x0800 // REFREC = 8 clocks oris r4, r4, 0x0040 // RDLAT = 4 clocks (CL+1) // oris r4, r4, 0x0030 // RDLAT = 3 clocks (CL+1) // rest of the bits are EDO only. stwbrx r4,0,r6 sync // ===MCCR4=== MEMORY CONTROL CONFIGURATION // addis r3,r0,BMC_BASE // Select MCCR4 (FC) ori r3,r3,0x00FC stwbrx r3,0,r5 sync lis r4, 0x3000 // PRETOACT = 3 clocks oris r4, r4, 0x0500 // ACTOPRE = 5 clocks // oris r4, r4, 0x0080 // Enable 8-beat burst (32-bit bus) // oris r4, r4, 0x0040 // Enable Inline ECC/Parity oris r4, r4, 0x0020 // Enable Extended ROM (RCS2/RCS3) oris r4, r4, 0x0010 // Registered buffers oris r4, r4, 0x0000 // BSTOPRE_U = 0 (see A/N) oris r4, r4, 0x0002 // Change RCS1 to 8-bit mode // ori r4, r4, 0x8000 // Registered DIMMs ori r4, r4, 0x3000 // CAS Latency (CL=3) (see RDLAT) // ori r4, r4, 0x2000 // CAS Latency (CL=2) (see RDLAT) ori r4, r4, 0x0200 // Sequential wrap/4-beat burst ori r4, r4, 0x0030 // ACTORW = 3 clocks ori r4, r4, 0x0009 // BSTOPRE_L = 9 (see A/N) // Set the SDRAM size to 4- or 8-beat bursts for 64- or 32-bit bus mode, // respectively. cmpi 0,0,r7,0x0 // test 32/64 bit mode beq c_is32bits ori r4, r4, 0x0200 // Sequential wrap/4-beat burst b mccr4set c_is32bits: ori r4, r4, 0x0300 // Sequential wrap/8-beat burst mccr4set: stwbrx r4,0,r6 sync // ===MSAR=== MEMORY START ADDRESS REGISTER // // MSAR1 / MSAR2 / MESAR1 / MESAR2 // // All eight registers are programmed to non-overlapping values. // Assuming each bank controls 32Mb, the maximum address per bank // is 0x1FFFFFF; we set each bank to start at 0x0000000, 0x2000000, etc. // Since the lower "00000" are implied, we see the pattern 0x00, 0x20, in // the start registers (with the extended addresses all 0s). addis r3,r0,BMC_BASE // Set MSAR1 (80) ori r3,r3,MEMSTARTADDR1 stwbrx r3,0,r5 addis r4,r0,0x6040 ori r4,r4,0x2000 stwbrx r4,0,r6 addis r3,r0,BMC_BASE // Set MSAR2 (84) ori r3,r3,MEMSTARTADDR2 stwbrx r3,0,r5 addis r4,r0,0xe0c0 ori r4,r4,0xa080 stwbrx r4,0,r6 addis r3,r0,BMC_BASE // Set MESAR1 (88) ori r3,r3,XMEMSTARTADDR1 stwbrx r3,0,r5 addis r4,r0,0x0000 ori r4,r4,0x0000 stwbrx r4,0,r6 addis r3,r0,BMC_BASE // Set MESAR2 (8c) ori r3,r3,XMEMSTARTADDR2 stwbrx r3,0,r5 addis r4,r0,0x0000 ori r4,r4,0x0000 stwbrx r4,0,r6 // ===MEAR=== MEMORY END ADDRESS REGISTER // // MEAR1 / MEAR2 / MEEAR1 / MEEAR2 // Similar to the previous values, less one from the next bank. // Therefore, 0x1F, 0x3F, etc. addis r3,r0,BMC_BASE // Set MEAR1 (90) ori r3,r3,MEMENDADDR1 stwbrx r3,0,r5 addis r4,r0,0x7f5f ori r4,r4,0x3f1f // ending address of bank 0 is // 0x0x01FFFFFF stwbrx r4,0,r6 addis r3,r0,BMC_BASE // Set MEAR2 (94) ori r3,r3,MEMENDADDR2 stwbrx r3,0,r5 addis r4,r0,0xffdf ori r4,r4,0xbf9f stwbrx r4,0,r6 addis r3,r0,BMC_BASE // MEEAR1 (98) = ori r3,r3,XMEMENDADDR1 stwbrx r3,0,r5 addis r4,r0,0x0000 ori r4,r4,0x0000 stwbrx r4,0,r6 addis r3,r0,BMC_BASE // MEEAR2 (9c) = ori r3,r3,XMEMENDADDR2 stwbrx r3,0,r5 addis r4,r0,0x0000 ori r4,r4,0x0000 stwbrx r4,0,r6 // ===ODCR=== OUTPUT DRIVER CONTROL CONFIGURATION // // NOTE: this is different than the MPC106! addis r3,r0,BMC_BASE // Select ODCR ori r3,r3,0x73 stwbrx r3,0,r5 sync lbz r4, 3(r6) // DBG: read current register state so // DBG: we can see it on the analyzer li r4, 0 ori r4, r4, 0x80 // PCI I/O: 50ohms (else 25ohm) ori r4, r4, 0x40 // CPU I/O: 40ohms (else 20ohm) // ori r4, r4, 0x30 // Mem I/O 8 ohms // ori r4, r4, 0x20 // Mem I/O: 13 ohms // ori r4, r4, 0x10 // Mem I/O: 20 ohms ori r4, r4, 0x00 // Mem I/O: 40 ohms // ori r4, r4, 0x0c // PCIClk: 8 ohms // ori r4, r4, 0x08 // PCIClk: 13 ohms // ori r4, r4, 0x04 // PCIClk: 20 ohms ori r4, r4, 0x00 // PCIClk: 40 ohms // ori r4, r4, 0x03 // MemClk: 8 ohms // ori r4, r4, 0x02 // MemClk: 13.3 ohms // ori r4, r4, 0x01 // MemClk: 20 ohms ori r4, r4, 0x00 // MemClk: 40 ohms stb r4, 3(r6) // New settings. sync // ===CDCR=== CLOCK DRIVER CONTROL REGISTER // addis r3, r0, BMC_BASE // Select CDCR ori r3, r3, 0x74 stwbrx r3, 0, r5 sync #ifdef GCC /* GCC compiler is broken. It will not accept a bit pattern greater than 0x8000 because it doesn't recognize signed 16 bit numbers. */ li r4, 0x7fff addi r4, r4, 1 // Equivalent to li r4,0x8000 #else li r4, 0x8000 // PCI_SYNC_OUT: disabled #endif /* GCC */ ori r4, r4, 0x7c00 // PCI_CLK(0:4): disabled // ori r4, r4, 0x0300 // CPU_CLK(0:1): 8 ohms // ori r4, r4, 0x0200 // CPU_CLK(0:1): 13 ohms // ori r4, r4, 0x0100 // CPU_CLK(0:1): 20 ohms ori r4, r4, 0x0000 // CPU_CLK(0:1): 40 ohms // ori r4, r4, 0x0080 // SDRAM_SYNC_OUT: disabled // ori r4, r4, 0x0078 // SDRAM_CLK(0:3): disabled // ori r4, r4, 0x0004 // CPU_CLK0: disabled // ori r4, r4, 0x0002 // CPU_CLK1: disabled ori r4, r4, 0x0001 // CPU_CLK2: disabled sthbrx r4, 0, r6 sync // ===MDCR=== MISC DRIVER CONTROL REGISTER // addis r3,r0,BMC_BASE // Select MDCR ori r3,r3,0x76 stwbrx r3,0,r5 sync li r4, 0x00 // ori r4, r4, 0x80 // MCP: 1=open-drain, 0=output ori r4, r4, 0x40 // SRESET: 1=open-drain, 0=output // ori r4, r4, 0x20 // QACK: 0=open-drain, 1=active drive stb r4, 2(r6) // New settings. sync // ===MBEN=== MEMORY BANK ENABLE // // Set a bit in MBEN for each enabled bank. We can have two on the // SODIMM. Each bank corresponds to a RAS/CS pin. addis r3,r0,BMC_BASE // Select MBEN (a0) ori r3,r3,0xa0 stwbrx r3,0,r5 sync li r4,0x03 // Enable banks 0 and 1 stb r4, 0(r6) // ===PGMAX=== Page Max // // Refer to the MPC106 SDRAM programming A/N for details (applies to // MPC107 also). addis r3,r0,BMC_BASE // Select PGMAX (a3) ori r3,r3,0xa3 stwbrx r3,0,r5 sync li r4, 0x0032 // 33 MHz - w/ROMFAL=8 // li r4, 0x0064 // 66 MHz - w/ROMFAL=8 // li r4, 0x0096 // 100 MHz - w/ROMFAL=8 stb r4, 3(r6) // Write PGMAX (note offset) // Wait before initializing other registers lis r4,0x0001 mtctr r4 Mpc107Wait200us: bdnz Mpc107Wait200us // Set MEMGO bit addis r3,r0,BMC_BASE // MCCR1 (F0) |= PGMAX ori r3,r3,0x00F0 stwbrx r3,0,r5 sync lwbrx r4,0,r6 // old MCCR1 lis r0, 0x0008 // MEMGO=1 ori r0, r0, 0x0000 or r4, r4, r0 // set the MEMGO bit stwbrx r4, 0, r6 // Wait again addis r4,r0,0x0002 ori r4,r4,0xffff mtctr r4 Mpc107wait8ref: bdnz Mpc107wait8ref //------ WP1_CNTL_TRIG addis r3,r0,BMC_BASE_HIGH // WP1_CNTL_TRIG (0xFF018) = ori r3,r3,0xF018 stwbrx r3,0,r5 addis r4,r0,0x0000 ori r4,r4,0x0180 stwbrx r4,0,r6 //------ WP1_ADDR_TRIG addis r3,r0,BMC_BASE_HIGH // WP1_ADDR_TRIG (0xFF01C) = ori r3,r3,0xF01C stwbrx r3,0,r5 addis r4,r0,0x0006 // Set to 0x60000 ori r4,r4,0x0000 stwbrx r4,0,r6 //------ WP1_CNTL_MASK addis r3,r0,BMC_BASE_HIGH // WP1_CNTL_MASK (0xFF020) = ori r3,r3,0xF020 stwbrx r3,0,r5 addis r4,r0,0x0000 ori r4,r4,0x0180 stwbrx r4,0,r6 //------ WP1_ADDR_MASK addis r3,r0,BMC_BASE_HIGH // WP1_ADDR_MASK (0xFF024) = ori r3,r3,0xF024 stwbrx r3,0,r5 addis r4,r0,0xFFFF ori r4,r4,0xFFFF stwbrx r4,0,r6 //------ WP_CONTROL addis r3,r0,BMC_BASE_HIGH // WP_CONTROL (0xFF048) = ori r3,r3,0xF048 stwbrx r3,0,r5 addis r4,r0,0x0000 ori r4,r4,0x01C6 stwbrx r4,0,r6 addis r4,r0,0x0100 // Enable Watchpoint on seperate write ori r4,r4,0x01C6 stwbrx r4,0,r6 sync eieio lis r3, 0x0 or r3, r3, r11 // restore Kahlua Vendor ID blr