Merge branch 'master' of git://git.denx.de/u-boot-ubi
[oweals/u-boot.git] / cpu / mpc8xx / plprcr_write.S
1 /*
2  * (C) Copyright 2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <mpc8xx.h>
25 #include <ppc_asm.tmpl>
26 #include <asm/cache.h>
27
28 #define CACHE_CMD_ENABLE        0x02000000
29 #define CACHE_CMD_DISABLE       0x04000000
30 #define CACHE_CMD_LOAD_LOCK     0x06000000
31 #define CACHE_CMD_UNLOCK_LINE   0x08000000
32 #define CACHE_CMD_UNLOCK_ALL    0x0A000000
33 #define CACHE_CMD_INVALIDATE    0x0C000000
34 #define SPEED_PLPRCR_WAIT_5CYC  150
35 #define _CACHE_ALIGN_SIZE       16
36
37
38         .text
39         .align 2
40         .globl plprcr_write_866
41
42 /*
43  * void plprcr_write_866 (long plprcr)
44  * Write PLPRCR, including workaround for device errata SIU4 and SIU9.
45  */
46
47 plprcr_write_866:
48         mfspr   r10, LR         /* save the Link Register value */
49
50         /* turn instruction cache on (no MMU required for instructions)
51          */
52         lis     r4, CACHE_CMD_ENABLE@h
53         ori     r4, r4, CACHE_CMD_ENABLE@l
54         mtspr   IC_CST, r4
55         isync
56
57         /* clear IC_CST error bits
58          */
59         mfspr   r4, IC_CST
60
61         bl      plprcr_here
62
63 plprcr_here:
64         mflr    r5
65
66         /* calculate relocation offset
67          */
68         lis     r4, plprcr_here@h
69         ori     r4, r4, plprcr_here@l
70         sub     r5, r5, r4
71
72         /* calculate first address of this function
73          */
74         lis     r6, plprcr_write_866@h
75         ori     r6, r6, plprcr_write_866@l
76         add     r6, r6, r5
77
78         /* calculate end address of this function
79          */
80         lis     r7, plprcr_end@h
81         ori     r7, r7, plprcr_end@l
82         add     r7, r7, r5
83
84         /* load and lock code addresses
85          */
86         mr      r5, r6
87
88 plprcr_loop:
89         mtspr   IC_ADR, r5
90         addi    r5, r5, _CACHE_ALIGN_SIZE       /* increment by one line */
91
92         lis     r4, CACHE_CMD_LOAD_LOCK@h
93         ori     r4, r4, CACHE_CMD_LOAD_LOCK@l
94         mtspr   IC_CST, r4
95         isync
96
97         cmpw    r5, r7
98         blt     plprcr_loop
99
100         /* IC_CST error bits not evaluated
101          */
102
103         /* switch PLPRCR
104          */
105         mfspr   r4, IMMR                /* read IMMR */
106         rlwinm  r4, r4, 0, 0, 15        /* only high 16 bits count */
107
108         /* write sequence according to MPC866 Errata
109          */
110         stw     r3, PLPRCR(r4)
111         isync
112
113         lis     r3, SPEED_PLPRCR_WAIT_5CYC@h
114         ori     r3, r3, SPEED_PLPRCR_WAIT_5CYC@l
115
116 plprcr_wait:
117         cmpwi   r3, 0
118         beq     plprcr_wait_end
119         nop
120         subi    r3, r3, 1
121         b       plprcr_wait
122
123 plprcr_wait_end:
124
125         /* unlock instruction cache but leave it enabled
126          */
127         lis     r4, CACHE_CMD_UNLOCK_ALL@h
128         ori     r4, r4, CACHE_CMD_UNLOCK_ALL@l
129         mtspr   IC_CST, r4
130         isync
131
132         mtspr   LR, r10         /* restore original Link Register value */
133         blr
134
135 plprcr_end: