OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [drivers/] [flash.c] - Blame information for rev 639

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 marcus.erl
#include "common.h"
2
#include "support.h"
3
#include "flash.h"
4
 
5
int fl_init (void)
6
{
7
  unsigned long tmp;
8
  reg_write(FLASH_BASE_ADDR, 0x00ff00ff);
9
  reg_write(FLASH_BASE_ADDR, 0x00900090);
10
  tmp = reg_read(FLASH_BASE_ADDR) << 8;
11
  reg_write(FLASH_BASE_ADDR, 0x00900090);
12
  tmp = tmp | reg_read(FLASH_BASE_ADDR + 4);
13
 
14
  debug("id = %08x ", tmp);
15
  /*  if (tmp != 0x89188918) {
16
    printf ("bad ID\n");
17
    return 1;
18
    } else debug ("good ID\n");*/
19
  reg_write(FLASH_BASE_ADDR, 0x00ff00ff);
20
 
21
  return 0;
22
}
23
 
24
int check_error (unsigned long sr, unsigned long addr)
25
{
26
  if(check_error_bit(sr, FL_SR_ERASE_ERR)) {
27
    printf ("erase error at %08lx\n", addr);
28
    /* Clear status register */
29
    reg_write(FLASH_BASE_ADDR, 0x05D00050);
30
    return 1;
31
  } else if (check_error_bit(sr, FL_SR_PROG_ERR)) {
32
    printf ("program error at %08lx\n", addr);
33
    /* Clear status register */
34
    reg_write(FLASH_BASE_ADDR, 0x05D00050);
35
    return 1;
36
  } else if (check_error_bit(sr, FL_SR_PROG_LV)) {
37
    printf ("low voltage error\n");
38
    /* Clear status register */
39
    reg_write(FLASH_BASE_ADDR, 0x05D00050);
40
    return 1;
41
  } else if (check_error_bit(sr, FL_SR_LOCK)) {
42
    printf ("lock bit error at %08lx\n", addr);
43
    /* Clear status register */
44
    reg_write(FLASH_BASE_ADDR, 0x05D00050);
45
    return 1;
46
  }
47
  return 0;
48
}
49
 
50
int fl_block_erase (unsigned long addr)
51
{
52
  unsigned long sr;
53
 
54
  reg_write(addr & ~(FLASH_BLOCK_SIZE - 1), 0x00200020);
55
  reg_write(addr & ~(FLASH_BLOCK_SIZE - 1), 0x00D000D0);
56
 
57
  do {
58
#if 0
59
    reg_write(FLASH_BASE_ADDR, 0x00700070);
60
#endif
61
    sr = reg_read(addr & ~(FLASH_BLOCK_SIZE - 1));
62
  } while (fl_wait_busy(sr));
63
 
64
  /* Clear status register */
65
  reg_write(FLASH_BASE_ADDR, 0x00500050);
66
  reg_write(FLASH_BASE_ADDR, 0x00ff00ff);
67
#ifndef CFG_IN_FLASH
68
  return check_error(sr, addr);
69
#else
70
  return 0;
71
#endif
72
}
73
 
74
int fl_unlock_one_block (unsigned long addr)
75
{
76
  unsigned long sr = 0x0;
77
 
78
  reg_write((addr & ~(FLASH_BLOCK_SIZE - 1)), 0x00600060);
79
  reg_write((addr & ~(FLASH_BLOCK_SIZE - 1)), 0x00d000d0);
80
 
81
  do {
82
#if 0
83
    reg_write(FLASH_BASE_ADDR, 0x00700070);
84
#endif
85
    sr = reg_read(addr & ~(FLASH_BLOCK_SIZE - 1));
86
  } while (fl_wait_busy(sr));
87
 
88
  /* Clear status register */
89
  reg_write(FLASH_BASE_ADDR, 0x00500050);
90
  reg_write(FLASH_BASE_ADDR, 0x00ff00ff);
91
 
92
#ifndef CFG_IN_FLASH
93
  return check_error(sr, addr);
94
#else
95
  return 0;
96
#endif
97
}
98
 
99
int fl_unlock_blocks (void)
100
{
101
  unsigned long c;
102
  unsigned int i;
103
 
104
  for (i = 0, c = FLASH_BASE_ADDR; i < (FLASH_SIZE / FLASH_BLOCK_SIZE);
105
       i++, c += FLASH_BLOCK_SIZE)
106
    if (fl_unlock_one_block (c)) return -1;
107
 
108
  return 0;
109
}
110
 
111
int fl_word_program (unsigned long addr, unsigned long val)
112
{
113
  unsigned long sr;
114
 
115
  reg_write(addr, 0x00400040);
116
  reg_write(addr, val);
117
  do {
118
#if FLASH_ORG_16_1 /* bender */
119
    reg_write(FLASH_BASE_ADDR, 0x00700070);
120
#endif
121
    sr = reg_read(addr & ~(FLASH_BLOCK_SIZE - 1));
122
  } while (fl_wait_busy(sr));
123
  /* Clear status register */
124
 
125
  reg_write(FLASH_BASE_ADDR, 0x00500050);
126
  reg_write(FLASH_BASE_ADDR, 0x00ff00ff);
127
#ifndef CFG_IN_FLASH
128
  return check_error(sr, addr);
129
#else
130
  return 0;
131
#endif
132
}
133
 
134
/* erase = 1 (whole chip), erase = 2 (required only) */
135
int fl_program (unsigned long src_addr, unsigned long dst_addr, unsigned long len, int erase, int verify)
136
{
137
  unsigned long tmp, taddr, tlen;
138
  unsigned long i;
139
 
140
  if (erase) {
141
    fl_unlock_blocks ();
142
 
143
    if (erase == 2) {
144
      taddr = dst_addr & ~(FLASH_BLOCK_SIZE - 1);
145
      tlen = (dst_addr + len + FLASH_BLOCK_SIZE - 1) / FLASH_BLOCK_SIZE;
146
    } else {
147
      taddr = FLASH_BASE_ADDR;
148
      tlen = FLASH_SIZE / FLASH_BLOCK_SIZE;
149
    }
150
 
151
    printf ("Erasing flash... ");
152
    for (i = 0, tmp = taddr; i < tlen; i++, tmp += FLASH_BLOCK_SIZE)
153
      if (fl_block_erase (tmp))
154
        return 1;
155
 
156
    printf ("done\n");
157
 
158
    if (verify) {
159
      printf ("Writing test pattern... ");
160
      for (tmp = taddr; tmp < taddr + tlen * FLASH_BLOCK_SIZE; i++, tmp += INC_ADDR)
161
        if (fl_word_program (tmp, tmp))
162
          return 1;
163
 
164
      printf ("done\n");
165
 
166
      printf ("Checking... ");
167
 
168
      for (tmp = taddr; tmp < taddr + tlen * FLASH_BLOCK_SIZE; i++, tmp += INC_ADDR)
169
        if (reg_read(tmp) != tmp) {
170
          printf ("failed on location %08lx: %08lx\n", tmp, REG32(tmp));
171
          return 1;
172
        }
173
      printf ("done\n");
174
    }
175
  }
176
 
177
  reg_write(FLASH_BASE_ADDR, 0x00ff00ff);
178
 
179
  printf ("Copying from %08lx-%08lx to %08lx-%08lx\n", src_addr, src_addr + len - 1, dst_addr, dst_addr + len - 1);
180
 
181
  tlen = len / 8;
182
  tmp = 0;
183
 
184
  printf ("Programing");
185
  for (i = 0; i < len; i += INC_ADDR) {
186
    if (fl_word_program (dst_addr + i, reg_read(src_addr + i)))
187
      return 1;
188
 
189
    if (i > tmp) {
190
      printf (".");
191
      tmp += tlen;
192
    }
193
  }
194
 
195
  printf (" done\n");
196
 
197
  if (verify) {
198
    printf ("Verifying");
199
    tmp = 0;
200
    for (i = 0; i < len; i += INC_ADDR) {
201
      if(reg_read(src_addr + i) != reg_read(dst_addr + i)) {
202
        printf ("error at %08lx: %lx != %lx\n", src_addr + i,
203
                reg_read(src_addr + i), reg_read(dst_addr + i));
204
        return 1;
205
      }
206
      if (i > tmp) {
207
        printf (".");
208
        tmp += tlen;
209
      }
210
    }
211
  }
212
 
213
  printf (" done\n");
214
  return 0;
215
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.