/* * cpu/spc300/dsp.S * * Copyright (C) 2010 SPiDCOM Technologies * * 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 */ #include #ifdef CONFIG_CHIP_FEATURE_SYNC_DSP_CLOCK #include .file "dsp.S" .text .arm @ This is ARM code; performs the same action as .code 32 .align 2 @ Align to word boundary; "2" means the number of bits that must be zero .globl dsp_init .type dsp_init, %function /* WARNING : Assume that for macros r0=MARIA_REGBANK_BASE and r1 is not used. */ .macro cmdoff, offset ldr r1, =CLK_CMD_OFF str r1, [r0, #\offset] .endm .macro cmdon, offset ldr r1, =CLK_CMD_ON str r1, [r0, #\offset] .endm .macro setreg, offset, val ldr r1, =\val str r1, [r0, #\offset] .endm .macro checkreg, offset, val 1: ldr r1, [r0, #\offset] cmp r1, #\val bne 1b .endm .macro setbit, regoffset, bitpos ldr r1, [r0, #\regoffset] orr r1, r1, #\bitpos str r1, [r0, #\regoffset] .endm .macro clrbit, regoffset, bitpos ldr r1, [r0, #\regoffset] bic r1, r1, #\bitpos str r1, [r0, #\regoffset] .endm dsp_init: ldr r0, =MARIA_REGBANK_BASE /* Set PHY CPU start instructions */ /* Later, we will have to release the PHY CPU reset. PHY CPU will execute * its start code in sdram, so we need to prepare it first. */ /* Change PHY processeur start address to SDRAM base addr */ setreg RB_LEON_ADD_START_OFFSET, 0x00000000 /* Set SDRAM with NOP instruction for PHY CPU */ ldr r2, =PHYS_SDRAM /* Physical address of PCPU for booting at 0 */ ldr r1, =0x01000000 /* NOP instruction for PCPU */ str r1, [r2], #4 str r1, [r2], #4 str r1, [r2], #4 str r1, [r2], #4 str r1, [r2], #4 str r1, [r2], #4 str r1, [r2], #4 str r1, [r2], #4 /* End Set PHY CPU start instructions */ /* Assert DSP reset, Normally already done. */ setbit RB_RST_GROUP_OFFSET, RST_DSP /* Disable DSP clock, Normally already done. */ cmdoff RB_CLK_CMD_DSP_OFFSET checkreg RB_CLK_STAT_DSP_OFFSET, CLK_IS_OFF /* Disable AFE clock, Normally already done. */ cmdoff RB_CLK_CMD_AFE_OFFSET checkreg RB_CLK_STAT_AFE_OFFSET, CLK_IS_OFF /* Enable AFE clock. */ cmdon RB_CLK_CMD_AFE_OFFSET checkreg RB_CLK_STAT_AFE_OFFSET, CLK_IS_ON /* Prepare register addresses needed during synchronisation process. */ ldr r7, =DSP_PRATIC_STA_LOCAL_TIMER ldr r6, =(MARIA_REGBANK_BASE+RB_CLK_CMD_DSP_OFFSET) ldr r5, =(MARIA_REGBANK_BASE+RB_RST_GROUP_OFFSET) /* Save RB_RST_GROUP register before changing LEONSS and DSP resets. */ ldr r4, [r5] /* * Synchronise DSP Clock and Reset for PRS patch. * Each cycle is important so forget macro using. */ /* We need to run this code twice because each instruction need to be * executed in cache so the first excecution is for cache filling. */ mov r3, #2 /* WARNING: From here, the number of clock cycles used by the SW must be * deterministic. */ .Lsyncdsp: mov r2, #0x20 .Lsearchclkphase: /* Switch off DSP clock. */ mov r1, #CLK_CMD_OFF str r1, [r6] /* Assert DSP reset and de-assert other groups then de-assert DSP reset. */ mov r1, #RST_DSP str r1, [r5] mov r1, #0 str r1, [r5] /* Switch on DSP clock after having released DSP reset to ensure that * PRATIC Timers change on falling edge of AFE Clock. */ mov r1, #CLK_CMD_ON str r1, [r6] /* Ensure synchronization of reset de-assertion on DSP AHB bus. */ nop nop nop nop nop nop /* Analyse clock phase */ /* Check that PRATIC Timer is equal to 2. This means that the previous ldr * has been performed at the middle of the high level of the AFE Clock * (any other values don't ensure phase locking). */ ldr r1, [r7] cmp r1, #2 nop beq .Lclkphasefound sub r2, r2, #1 cmp r2, #0 bne .Lsearchclkphase .Lclkphasefound: /* Assert DSP reset and de-assert other groups then de-assert DSP reset. */ mov r1, #RST_DSP str r1, [r5] mov r1, #0 str r1, [r5] sub r3, r3, #1 cmp r3, #0 bne .Lsyncdsp /* Restore RB_RST_GROUP register after changing LEONSS and DSP resets. */ /* But don't reset DSP. */ bic r4, r4, #RST_DSP str r4, [r5] /* Back to my caller. */ mov pc, lr #endif /* CONFIG_CHIP_FEATURE_SYNC_DSP_CLOCK */