summaryrefslogtreecommitdiff
path: root/cleopatre/u-boot-1.1.6/cpu/spc300/dsp.S
blob: bc3a16fe71c4a772764a869a807a65289656bbf5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
 * 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 <config.h>

#ifdef CONFIG_CHIP_FEATURE_SYNC_DSP_CLOCK

#include <asm/hardware.h>

    .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 */