/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id: $ * * Copyright (C) 2010 by Karl Kurbjun * * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "config.h" #include "cpu.h" #define SDRAM_MODE 0x9B00 /* Macro for reading a register */ .macro mrh register ldr r1, =\register ldrh r0, [r1] .endm /* Macro for writing a register */ .macro mwh register, value ldr r0, =\value ldr r1, =\register strh r0, [r1] .endm /* This version uses a mov to save on the literal pool size. Otherwise it is * functionally equivalent. */ .macro mwhm register, value mov r0, #\value ldr r1, =\register strh r0, [r1] .endm /****************************************************************************** * _init_board: * * This function initializes the specific baord this SoC is on. * ******************************************************************************/ .section .init, "ax" .code 32 .align 0x04 .global _init_board .type _init_board, %function _init_board: /* Setup the EMIF interface timings */ /* FLASH interface: * These are based on the OF setup */ /* IO_EMIF_CS0CTRL1 and * IO_EMIF_CS0CTRL2 */ mwh 0x30A00, 0x4488 mwh 0x30A02, 0x1220 /* ATA interface: * These are based on the OF setup */ /* IO_EMIF_CS3CTRL1 and * IO_EMIF_CS3CTRL2 */ mwh 0x30A10, 0x77EF mwh 0x30A12, 0x5220 /* USB interface: * The following EMIF timing values are from the OF: * IO_EMIF_CS4CTRL1 = 0x66AB; * IO_EMIF_CS4CTRL2 = 0x4220; * * More agressive numbers may be possible, but it depends on the clocking * setup. */ /* IO_EMIF_CS4CTRL1 and * IO_EMIF_CS4CTRL2 */ mwh 0x30A14, 0x66AB mwh 0x30A16, 0x4220 /* IO_EMIF_BUSCTRL */ mwh 0x30A18, 0x0001 _clock_setup: /* Clock initialization */ /* Used for ES10 and unknown, slower clocks, but also uses more power * due to PLL setup and slow ARM clock speed. */ /* IO_CLK_BYP: Bypass the PLLs for the following changes */ mwh 0x30894, 0x1111 /* 27 MHz input clock: * IO_CLK_PLLA = 27 * 11 / 1 = 297 MHz * IO_CLK_PLLB = 27 * 13 / 1 = 351 MHz */ mwh 0x30880, 0x10A0 mwh 0x30882, 0x10C0 /* IO_CLK_SEL0: VLNQ is fed by PLLB, I2C from M48XI, MS from PLLA */ mwh 0x30884, 0x17E /* IO_CLK_SEL1: VENC = MXI CLK, PLLA, PCLK, nodiv2 */ mwhm 0x30886, 0x1000 # IO_CLK_SEL2: ARM and AXL are from PLLB, SDRAM and DSP are PLLA */ mwh 0x30888, 0x1001 /* IO_CLK_DIV0: Set the slow clock speed for the ARM/AHB * Slow Setup: * ARM div = 4 ( 87.5 MHz ) * AHB div = 1 ( 87.5 MHz ) */ mwh 0x3088A, 0x0003 /* OF sets this to 0x0103 */ /* IO_CLK_DIV1: * SDRAM div= 3 ( 99 MHz ) * AXL div = 2 ( 175 MHz ) */ mwh 0x3088C, 0x0102 /* OF sets this to 0x0103 */ /* IO_CLK_DIV2: * MS div = 32 ( ~9 MHz ) * DSP div = 3 ( 99 MHz ) */ mwh 0x3088E, 0x020E /* IO_CLK_DIV3: (this comment is incorrect, (31 << 8) | 255;) * MMC div = 256 ( slow ) * VENC div = 32 ( 843.75 KHz ) */ mwhm 0x30890, 0x0003 /* IO_CLK_DIV4: (this comment is incorrect, (31 << 8) | 0;) * I2C div = 1 (48 MHz if M48XI is running) * VLNQ div = 32 */ mwhm 0x30892, 0x0200 # PLLA &= ~0x1000 (BIC #0x1000) mrh 0x30880 bic r0, r0, #0x1000 strh r0, [r1] # PLLB &= ~0x1000 mrh 0x30882 bic r0, r0, #0x1000 strh r0, [r1] /* Wait for PLLs to lock before feeding them to the downstream devices */ _plla_wait: mrh 0x30880 bic r0, r0, #0x7F tst r0, r0 beq _plla_wait _pllb_wait: mrh 0x30882 bic r0, r0, #0x7F tst r0, r0 beq _plla_wait /* IO_CLK_BYP: Enable PLL feeds */ mwhm 0x30894, 0x0 /* IO_CLK_MOD0: Most off */ mwh 0x30898, 0x0167 /* IO_CLK_MOD1: All off */ mwhm 0x3089A, 0x0 /* IO_CLK_MOD2: Turn on the GPIO clock */ mwhm 0x3089C, 0x20 /* Setup the SDRAM range on the AHB bus */ /* SDRAMSA */ mov r0, #0x60000 mov r1, #0x900000 str r1, [r0, #0xF00] /* SDRAMEA: 64MB */ mov r1, #0x4900000 str r1, [r0, #0xF04] /* BUSCTRL */ mov r1, #0x00000 str r1, [r0, #0xF08] /* USBCTRL */ str r1, [r0, #0xF20] /* Setup IO_SDRAM_SDMODE based on OF */ mov r1, #0x00030000 orr r1, r1, #0x900 /* Pre-charge all banks */ ldr r0, =(SDRAM_MODE | 0x82) strh r0, [r1, #0xA6] /* Setup auto refresh, OF uses 0x5F */ ldr r0, =0x140 strh r0, [r1, #0xA8] /* Issue 8 auto refresh cycles */ ldr r0, =(SDRAM_MODE | 0x84) strh r0, [r1, #0xA6] strh r0, [r1, #0xA6] strh r0, [r1, #0xA6] strh r0, [r1, #0xA6] strh r0, [r1, #0xA6] strh r0, [r1, #0xA6] strh r0, [r1, #0xA6] strh r0, [r1, #0xA6] /* Set the mode register */ ldr r0, =(SDRAM_MODE | 0x81) strh r0, [r1, #0xA6] /* Go back to the NOP state */ ldr r0, =(SDRAM_MODE | 0x80) strh r0, [r1, #0xA6] /* Turn on auto power down */ ldr r0, =(SDRAM_MODE | 0x40) strh r0, [r1, #0xA6] /* Go through the GPIO initialization */ /* IO_GIO_FSEL0: Set up the GPIO pin functions 0-16 */ mwh 0x305A4, 0x0000 /* IO_GIO_FSEL1: 17-24 */ mwh 0x305A6, 0x0000 /* IO_GIO_FSEL2: 18-32 */ mwh 0x305A8, 0x1450 /* IO_GIO_FSEL3: 33-40 */ mwh 0x305AA, 0x0404 /* IO_GIO_DIR0 */ mwh 0x30580, 0x6A0B /* IO_GIO_DIR1: Important note - pin 26 has control over the system power. * If this pin is not initialized the device will shut off immediately. */ mwh 0x30582, 0x8B00 /* IO_GIO_DIR2 */ mwh 0x30584, 0x0000 /* IO_GIO_INV0 */ mwh 0x30586, 0x0000 /* IO_GIO_INV1 */ mwh 0x30588, 0x0000 /* IO_GIO_INV2 */ mwh 0x3058A, 0x0000 /* IO_GIO_BITCLR0 */ mwh 0x30592, 0xFFFF /* IO_GIO_BITCLR1 */ mwh 0x30594, 0xFFFF /* IO_GIO_BITCLR2 */ mwh 0x30596, 0xFFFF /* IO_GIO_BITSET0 */ mwh 0x3058C, 0x0280 /* IO_GIO_BITSET1 */ mwh 0x3058E, 0x2066 /* IO_GIO_BITSET2 */ mwh 0x30590, 0x0025 /* IO_GIO_IRQPORT */ mwh 0x30598, 0xD60B /* IO_GIO_IRQEDGE */ mwh 0x3059A, 0x0801 /* IO_GIO_CHAT0 */ mwh 0x3059C, 0x0000 /* IO_GIO_CHAT1 */ mwh 0x3059E, 0x0000 /* IO_GIO_CHAT2 */ mwh 0x305A0, 0x0000 /* IO_GIO_NCHAT */ mwh 0x305A2, 0x0000 bx lr .ltorg .size _init_board, .-_init_board