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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [orpmon/] [drivers/] [flash.c] - Blame information for rev 828

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

Line No. Rev Author Line
1 814 markom
#include "common.h"
2
#include "support.h"
3
#include "flash.h"
4
 
5
/* Returns nonzero if there is an error */
6
int fl_init (void)
7
{
8
  unsigned long tmp;
9 816 markom
  REG32(FLASH_BASE_ADDR) = 0x00ff00ff;
10 814 markom
 
11 816 markom
  REG32(FLASH_BASE_ADDR) = 0x00900090;
12
  tmp = REG32(FLASH_BASE_ADDR) << 8;
13
  REG32(FLASH_BASE_ADDR) = 0x00900090;
14
  tmp = tmp | REG32(FLASH_BASE_ADDR + 4);
15 814 markom
  debug("id = %08x ", tmp);
16
  if (tmp != 0x89188918) {
17 816 markom
    printf ("bad ID\n");
18 814 markom
    return 1;
19
  } else debug ("good ID\n");
20 816 markom
  REG32(FLASH_BASE_ADDR) = 0x00ff00ff;
21 814 markom
  return 0;
22
}
23
 
24 816 markom
int check_error (unsigned long sr, unsigned long addr)
25 814 markom
{
26 816 markom
  if ((sr & (FL_SR_ERASE_ERR << 16)) || (sr & FL_SR_ERASE_ERR)) {
27
    printf ("erase error at %08lx\n", addr);
28
    /* Clear status register */
29
    REG32(FLASH_BASE_ADDR) = 0x05D00050;
30
    return 1;
31
  } else if ((sr & (FL_SR_PROG_ERR << 16)) || (sr & FL_SR_PROG_ERR)) {
32
    printf ("program error at %08lx\n", addr);
33
    /* Clear status register */
34
    REG32(FLASH_BASE_ADDR) = 0x05D00050;
35
    return 1;
36
  } else if ((sr & (FL_SR_PROG_LV << 16)) || (sr & FL_SR_PROG_LV)) {
37
    printf ("low voltage error\n");
38
    /* Clear status register */
39
    REG32(FLASH_BASE_ADDR) = 0x05D00050;
40
    return 1;
41
  } else if ((sr & (FL_SR_LOCK << 16)) || (sr & FL_SR_LOCK)) {
42
    printf ("lock bit error at %08lx\n", addr);
43
    /* Clear status register */
44
    REG32(FLASH_BASE_ADDR) = 0x05D00050;
45
    return 1;
46
  }
47
  return 0;
48
}
49
 
50
int fl_block_erase (unsigned long addr)
51
{
52 814 markom
  unsigned long sr;
53
 
54 816 markom
  REG32(addr & ~(FLASH_BLOCK_SIZE - 1)) = 0x00200020;
55
  REG32(addr & ~(FLASH_BLOCK_SIZE - 1)) = 0x00D000D0;
56 814 markom
 
57
  do {
58 816 markom
    REG32(FLASH_BASE_ADDR) = 0x00700070;
59
    sr = REG32(FLASH_BASE_ADDR);
60 814 markom
  } while (!(sr & (FL_SR_WSM_READY << 16)) || !(sr & FL_SR_WSM_READY));
61
 
62 816 markom
  REG32(FLASH_BASE_ADDR) = 0x00ff00ff;
63
  return check_error (sr, addr);
64
}
65 814 markom
 
66 816 markom
int fl_unlock_blocks (void)
67
{
68
  unsigned long sr;
69
 
70
  printf ("Clearing all lock bits... ");
71
  REG32(FLASH_BASE_ADDR) = 0x00600060;
72
  REG32(FLASH_BASE_ADDR) = 0x00d000d0;
73 814 markom
 
74 816 markom
  do {
75
    REG32(FLASH_BASE_ADDR) = 0x00700070;
76
    sr = REG32(FLASH_BASE_ADDR);
77
  } while (!(sr & (FL_SR_WSM_READY << 16)) || !(sr & FL_SR_WSM_READY));
78
  printf ("done\n");
79
  return check_error (sr, FLASH_BASE_ADDR);
80 814 markom
}
81
 
82 816 markom
int fl_word_program (unsigned long addr, unsigned long val)
83 814 markom
{
84
  unsigned long sr;
85
 
86
  REG32(addr) = 0x00400040;
87
  REG32(addr) = val;
88
 
89
  do {
90 816 markom
    REG32(FLASH_BASE_ADDR) = 0x00700070;
91
    sr = REG32(FLASH_BASE_ADDR);
92 814 markom
  } while (!(sr & (FL_SR_WSM_READY << 16)) || !(sr & FL_SR_WSM_READY));
93
 
94 816 markom
  REG32(FLASH_BASE_ADDR) = 0x00ff00ff;
95
  return check_error (sr, addr);
96
}
97 814 markom
 
98 816 markom
/* erase = 1 (whole chip), erase = 2 (required only) */
99
int fl_program (unsigned long src_addr, unsigned long dst_addr, unsigned long len, int erase, int verify)
100
{
101
  unsigned long tmp, taddr, tlen;
102
  unsigned long i;
103
 
104
  if (erase) {
105
    fl_unlock_blocks ();
106
 
107
    if (erase == 2) {
108
      taddr = dst_addr & ~(FLASH_BLOCK_SIZE - 1);
109
      tlen = (dst_addr + len + FLASH_BLOCK_SIZE - 1) / FLASH_BLOCK_SIZE;
110
    } else {
111
      taddr = FLASH_BASE_ADDR;
112
      tlen = FLASH_SIZE / FLASH_BLOCK_SIZE;
113
    }
114
 
115
    printf ("Erasing flash... ");
116
    for (i = 0, tmp = taddr; i < tlen; i++, tmp += FLASH_BLOCK_SIZE)
117
      if (fl_block_erase (tmp)) return 1;
118
    printf ("done\n");
119
 
120
    if (verify) {
121
      printf ("Writing test pattern... ");
122
      for (tmp = taddr; tmp < taddr + tlen * FLASH_BLOCK_SIZE; i++, tmp += 4)
123
        if (fl_word_program (tmp, tmp)) return 1;
124
      printf ("done\n");
125
 
126
      printf ("Checking... ");
127
      for (tmp = taddr; tmp < taddr + tlen * FLASH_BLOCK_SIZE; i++, tmp += 4)
128
        if (REG32(tmp) != tmp) {
129
          printf ("failed on location %08lx: %08lx\n", tmp, REG32(tmp));
130
          return 1;
131
        }
132
      printf ("done\n");
133
    }
134
  }
135
 
136
  REG32(FLASH_BASE_ADDR) = 0x00ff00ff;
137
  printf ("Copying from %08lx-%08lx to %08lx-%08lx\n", src_addr, src_addr + len - 1, dst_addr, dst_addr + len - 1);
138 814 markom
 
139 816 markom
  tlen = len / 8;
140
  tmp = 0;
141
  printf ("Programing");
142
  for (i = 0; i < len; i += 4) {
143
    if (fl_word_program (dst_addr + i, REG32(src_addr + i))) return 1;
144
    if (i > tmp) {
145
      printf (".");
146
      tmp += tlen;
147 814 markom
    }
148 816 markom
  }
149
  printf (" done\n");
150
 
151
  if (verify) {
152
    printf ("Verifying");
153
    tmp = 0;
154
    for (i = 0; i < len; i += 4) {
155
      if (REG32(src_addr + i) != REG32(dst_addr + i)) {
156 828 markom
        printf ("error at %08lx: %08lx != %08lx\n", src_addr + i, REG32(src_addr + i), REG32(dst_addr + i));
157 816 markom
        return 1;
158
      }
159
      if (i > tmp) {
160
        printf (".");
161
        tmp += tlen;
162
      }
163 814 markom
    }
164 816 markom
  }
165
  printf (" done\n");
166
  return 0;
167 814 markom
}

powered by: WebSVN 2.1.0

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