uboot/board/altera/common/flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000-2004
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8
   9#include <common.h>
  10#include <nios.h>
  11
  12flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  13
  14/*--------------------------------------------------------------------*/
  15void flash_print_info (flash_info_t * info)
  16{
  17        int i, k;
  18        unsigned long size;
  19        int erased;
  20        volatile unsigned char *flash;
  21
  22        printf ("  Size: %ld KB in %d Sectors\n",
  23                info->size >> 10, info->sector_count);
  24        printf ("  Sector Start Addresses:");
  25        for (i = 0; i < info->sector_count; ++i) {
  26
  27                /* Check if whole sector is erased */
  28                if (i != (info->sector_count - 1))
  29                        size = info->start[i + 1] - info->start[i];
  30                else
  31                        size = info->start[0] + info->size - info->start[i];
  32                erased = 1;
  33                flash = (volatile unsigned char *) info->start[i];
  34                for (k = 0; k < size; k++) {
  35                        if (*flash++ != 0xff) {
  36                                erased = 0;
  37                                break;
  38                        }
  39                }
  40
  41                /* Print the info */
  42                if ((i % 5) == 0)
  43                        printf ("\n   ");
  44                printf (" %08lX%s%s", info->start[i], erased ? " E" : "  ",
  45                        info->protect[i] ? "RO " : "   ");
  46        }
  47        printf ("\n");
  48}
  49
  50/*-------------------------------------------------------------------*/
  51
  52
  53int flash_erase (flash_info_t * info, int s_first, int s_last)
  54{
  55        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
  56        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
  57        int prot, sect;
  58        unsigned oldpri;
  59        ulong start;
  60
  61        /* Some sanity checking */
  62        if ((s_first < 0) || (s_first > s_last)) {
  63                printf ("- no sectors to erase\n");
  64                return 1;
  65        }
  66
  67        prot = 0;
  68        for (sect = s_first; sect <= s_last; ++sect) {
  69                if (info->protect[sect]) {
  70                        prot++;
  71                }
  72        }
  73        if (prot) {
  74                printf ("- Warning: %d protected sectors will not be erased!\n",
  75                        prot);
  76        } else {
  77                printf ("\n");
  78        }
  79
  80#ifdef DEBUG
  81        for (sect = s_first; sect <= s_last; sect++) {
  82                printf("- Erase: Sect: %i @ 0x%08x\n", sect,  info->start[sect]);
  83        }
  84#endif
  85
  86        /* NOTE: disabling interrupts on Nios can be very bad since it
  87         * also disables the LO_LIMIT exception. It's better here to
  88         * set the interrupt priority to 3 & restore it when we're done.
  89         */
  90        oldpri = ipri (3);
  91
  92        /* It's ok to erase multiple sectors provided we don't delay more
  93         * than 50 usec between cmds ... at which point the erase time-out
  94         * occurs. So don't go and put printf() calls in the loop ... it
  95         * won't be very helpful ;-)
  96         */
  97        for (sect = s_first; sect <= s_last; sect++) {
  98                if (info->protect[sect] == 0) { /* not protected */
  99                        addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
 100                        *addr = 0xaa;
 101                        *addr = 0x55;
 102                        *addr = 0x80;
 103                        *addr = 0xaa;
 104                        *addr = 0x55;
 105                        *addr2 = 0x30;
 106                        /* Now just wait for 0xff & provide some user
 107                         * feedback while we wait. Here we have to grant
 108                         * timer interrupts. Otherwise get_timer() can't
 109                         * work right. */
 110                        ipri(oldpri);
 111                        start = get_timer (0);
 112                        while (*addr2 != 0xff) {
 113                                udelay (1000 * 1000);
 114                                putc ('.');
 115                                if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 116                                        printf ("timeout\n");
 117                                        return 1;
 118                                }
 119                        }
 120                        oldpri = ipri (3); /* disallow non important irqs again */
 121                }
 122        }
 123
 124        printf ("\n");
 125
 126        /* Restore interrupt priority */
 127        ipri (oldpri);
 128
 129        return 0;
 130}
 131
 132/*-----------------------------------------------------------------------
 133 * Copy memory to flash, returns:
 134 * 0 - OK
 135 * 1 - write timeout
 136 * 2 - Flash not erased
 137 */
 138
 139int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 140{
 141
 142        vu_char *cmd = (vu_char *) info->start[0];
 143        vu_char *dst = (vu_char *) addr;
 144        unsigned char b;
 145        unsigned oldpri;
 146        ulong start;
 147
 148        while (cnt) {
 149                /* Check for sufficient erase */
 150                b = *src;
 151                if ((*dst & b) != b) {
 152                        printf ("%02x : %02x\n", *dst, b);
 153                        return (2);
 154                }
 155
 156                /* Disable interrupts other than window underflow
 157                 * (interrupt priority 2)
 158                 */
 159                oldpri = ipri (3);
 160                *cmd = 0xaa;
 161                *cmd = 0x55;
 162                *cmd = 0xa0;
 163                *dst = b;
 164
 165                /* Verify write */
 166                start = get_timer (0);
 167                while (*dst != b) {
 168                        if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 169                                ipri (oldpri);
 170                                return 1;
 171                        }
 172                }
 173                dst++;
 174                src++;
 175                cnt--;
 176                ipri (oldpri);
 177        }
 178
 179        return (0);
 180}
 181