FreeCalypso > hg > tcs211-l1-reconst
comparison chipsetsw/drivers/drv_app/ffs/board/amdsbdrv.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:509db1a7b7b8 |
---|---|
1 /****************************************************************************** | |
2 * Flash File System (ffs) | |
3 * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com | |
4 * | |
5 * FFS AMD single bank low level flash driver RAM code | |
6 * | |
7 * $Id: amdsbdrv.c 1.5.1.3 Tue, 06 Jan 2004 10:57:45 +0100 tsj $ | |
8 * | |
9 ******************************************************************************/ | |
10 | |
11 #include "ffs.cfg" | |
12 | |
13 #include "ffs/ffs.h" | |
14 #include "ffs/board/drv.h" | |
15 #include "ffs/board/ffstrace.h" | |
16 | |
17 | |
18 // Due to long branches, we disable all tracing and led function calls. | |
19 #undef tlw | |
20 #define tlw(contents) | |
21 #undef ttw | |
22 #define ttw(contents) | |
23 | |
24 | |
25 asm(" .label _ffsdrv_ram_amd_begin"); | |
26 asm(" .def _ffsdrv_ram_amd_begin"); | |
27 | |
28 | |
29 // IMPORTANT! Apparently, placing the int_disable/enable() function code | |
30 // here instead of at the bottom of the file, makes the code crash or | |
31 // freeze. Reason is as of yet unknown. | |
32 | |
33 uint32 amd_int_disable(void); | |
34 void amd_int_enable(uint32 tmp); | |
35 | |
36 | |
37 /****************************************************************************** | |
38 * AMD Single Bank Driver Functions | |
39 ******************************************************************************/ | |
40 | |
41 void ffsdrv_ram_amd_sb_write_halfword(volatile uint16 *addr, uint16 value) | |
42 { | |
43 volatile char *flash = dev.base; | |
44 uint32 cpsr; | |
45 | |
46 ttw(ttr(TTrDrv, "wh(%x,%x)" NL, addr, value)); | |
47 | |
48 if (~*addr & value) { | |
49 ttw(ttr(TTrFatal, "wh(%x,%x->%x) fatal" NL, addr, *addr, value)); | |
50 return; | |
51 } | |
52 | |
53 cpsr = amd_int_disable(); | |
54 tlw(led_on(LED_WRITE)); | |
55 | |
56 flash[0xAAAA] = 0xAA; // AMD unlock cycle 1 | |
57 flash[0x5555] = 0x55; // AMD unlock cycle 2 | |
58 flash[0xAAAA] = 0xA0; | |
59 *addr = value; | |
60 | |
61 while ((*addr ^ value) & 0x80) | |
62 ; | |
63 | |
64 tlw(led_off(LED_WRITE)); | |
65 amd_int_enable(cpsr); | |
66 } | |
67 | |
68 // This VERY simple way of erase suspension only works because we run under | |
69 // a pre-emptive operating system, so whenever an interrupt occurs, another | |
70 // task takes the CPU, and at the end of the interrupt, FFS gets the CPU | |
71 // again. | |
72 void ffsdrv_ram_amd_sb_erase(uint8 block) | |
73 { | |
74 volatile char *flash = dev.base; | |
75 volatile char *addr; | |
76 uint32 cpsr; | |
77 uint16 flashpoll; | |
78 | |
79 addr = block2addr(block); | |
80 | |
81 ttw(ttr(TTrDrvEra, "e(%d)" NL, block)); | |
82 | |
83 cpsr = amd_int_disable(); | |
84 tlw(led_on(LED_ERASE)); | |
85 | |
86 flash[0xAAAA] = 0xAA; // AMD unlock cycle 1 | |
87 flash[0x5555] = 0x55; // AMD unlock cycle 2 | |
88 flash[0xAAAA] = 0x80; | |
89 flash[0xAAAA] = 0xAA; // AMD unlock cycle 1 | |
90 flash[0x5555] = 0x55; // AMD unlock cycle 2 | |
91 *addr = 0x30; // AMD erase sector command | |
92 | |
93 // Wait for erase to finish. | |
94 while ((*addr & 0x80) == 0) { | |
95 tlw(led_toggle(LED_ERASE)); | |
96 // Poll interrupts, taking interrupt mask into account. | |
97 if (INT_REQUESTED) | |
98 { | |
99 // 1. suspend erase | |
100 // 2. enable interrupts | |
101 // .. now the interrupt code executes | |
102 // 3. disable interrupts | |
103 // 4. resume erase | |
104 | |
105 tlw(led_on(LED_ERASE_SUSPEND)); | |
106 *addr = 0xB0; | |
107 | |
108 // wait for erase suspend to finish | |
109 while ((*addr & 0x80) == 0) | |
110 ; | |
111 | |
112 tlw(led_off(LED_ERASE_SUSPEND)); | |
113 amd_int_enable(cpsr); | |
114 | |
115 // Other interrupts and tasks run now... | |
116 | |
117 cpsr = amd_int_disable(); | |
118 tlw(led_on(LED_ERASE_SUSPEND)); | |
119 | |
120 // Before resuming erase we must? check if the erase is really | |
121 // suspended or if it did finish | |
122 flashpoll = *addr; | |
123 *addr = 0x30; | |
124 | |
125 tlw(led_off(LED_ERASE_SUSPEND)); | |
126 } | |
127 } | |
128 | |
129 tlw(led_on(LED_ERASE)); | |
130 tlw(led_off(LED_ERASE)); | |
131 amd_int_enable(cpsr); | |
132 } | |
133 | |
134 | |
135 /****************************************************************************** | |
136 * Interrupt Enable/Disable | |
137 ******************************************************************************/ | |
138 | |
139 uint32 amd_int_disable(void) | |
140 { | |
141 asm(" .state16"); | |
142 asm(" mov A1, #0xC0"); | |
143 asm(" ldr A2, tct_amd_disable"); | |
144 asm(" bx A2 "); | |
145 | |
146 asm("tct_amd_disable .field _TCT_Control_Interrupts+0,32"); | |
147 asm(" .global _TCT_Control_Interrupts"); | |
148 } | |
149 | |
150 void amd_int_enable(uint32 cpsr) | |
151 { | |
152 asm(" .state16"); | |
153 asm(" ldr A2, tct_amd_enable"); | |
154 asm(" bx A2 "); | |
155 | |
156 asm("tct_amd_enable .field _TCT_Control_Interrupts+0,32"); | |
157 asm(" .global _TCT_Control_Interrupts"); | |
158 } | |
159 | |
160 // Even though we have this end label, we cannot determine the number of | |
161 // constant/PC-relative data following the code! | |
162 asm(" .state32"); | |
163 asm(" .label _ffsdrv_ram_amd_end"); | |
164 asm(" .def _ffsdrv_ram_amd_end"); |