uboot/board/BuS/EB+MCF-EV123/cfm_flash.c
<<
>>
Prefs
   1/*
   2 * Basic Flash Driver for Freescale MCF 5281/5282 internal FLASH
   3 *
   4 * (C) Copyright 2005 BuS Elektronik GmbH & Co.KG <esw@bus-elektonik.de>
   5 *
   6 * See file CREDITS for list of people who contributed to this
   7 * project.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation; either version 2 of
  12 * the License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22 * MA 02111-1307 USA
  23 */
  24
  25#include <common.h>
  26#include <asm/m5282.h>
  27#include  "cfm_flash.h"
  28
  29#if defined(CONFIG_M5281) || defined(CONFIG_M5282)
  30
  31#if (CONFIG_SYS_CLK>20000000)
  32        #define CFM_CLK  (((long) CONFIG_SYS_CLK / (400000 * 8) + 1) | 0x40)
  33#else
  34        #define CFM_CLK  ((long) CONFIG_SYS_CLK / 400000 + 1)
  35#endif
  36
  37#define cmf_backdoor_address(addr)      (((addr) & 0x0007FFFF) | 0x04000000 | \
  38                                         (CONFIG_SYS_MBAR & 0xC0000000))
  39
  40void cfm_flash_print_info (flash_info_t * info)
  41{
  42        printf ("Freescale: ");
  43        switch (info->flash_id & FLASH_TYPEMASK) {
  44        case FREESCALE_ID_MCF5281 & FLASH_TYPEMASK:
  45                printf ("MCF5281 internal FLASH\n");
  46                break;
  47        case FREESCALE_ID_MCF5282 & FLASH_TYPEMASK:
  48                printf ("MCF5282 internal FLASH\n");
  49                break;
  50        default:
  51                printf ("Unknown Chip Type\n");
  52                break;
  53        }
  54}
  55
  56void cfm_flash_init (flash_info_t * info)
  57{
  58        int sector;
  59        ulong protection;
  60        MCFCFM_MCR = 0;
  61        MCFCFM_CLKD = CFM_CLK;
  62        debug ("CFM Clock divider: %ld (%d Hz @ %ld Hz)\n",CFM_CLK,\
  63                CONFIG_SYS_CLK / (2* ((CFM_CLK & 0x3F)+1) * (1+((CFM_CLK & 0x40)>>6)*7)),\
  64                CONFIG_SYS_CLK);
  65        MCFCFM_SACC = 0;
  66        MCFCFM_DACC = 0;
  67
  68        if (MCFCFM_SEC & MCFCFM_SEC_KEYEN)
  69                puts("CFM backdoor access is enabled\n");
  70        if (MCFCFM_SEC & MCFCFM_SEC_SECSTAT)
  71                puts("CFM securety is enabled\n");
  72
  73        #ifdef CONFIG_M5281
  74                info->flash_id = (FREESCALE_MANUFACT & FLASH_VENDMASK) |
  75                                 (FREESCALE_ID_MCF5281 & FLASH_TYPEMASK);
  76                info->size = 256*1024;
  77                info->sector_count = 16;
  78        #else
  79                info->flash_id = (FREESCALE_MANUFACT & FLASH_VENDMASK) |
  80                                 (FREESCALE_ID_MCF5282 & FLASH_TYPEMASK);
  81                info->size = 512*1024;
  82                info->sector_count = 32;
  83        #endif
  84        protection = MCFCFM_PROT;
  85        for (sector = 0; sector < info->sector_count; sector++)
  86        {
  87                if (sector == 0)
  88                {
  89                        info->start[sector] = CONFIG_SYS_INT_FLASH_BASE;
  90                }
  91                else
  92                {
  93                        info->start[sector] = info->start[sector-1] + 0x04000;
  94                }
  95                info->protect[sector] = protection & 1;
  96                protection >>= 1;
  97        }
  98}
  99
 100int cfm_flash_readycheck(int checkblank)
 101{
 102        int     rc;
 103        unsigned char state;
 104
 105        rc      = ERR_OK;
 106        while (!(MCFCFM_USTAT & MCFCFM_USTAT_CCIF));
 107        state = MCFCFM_USTAT;
 108        if (state & MCFCFM_USTAT_ACCERR)
 109        {
 110                debug ("%s(): CFM access error",__FUNCTION__);
 111                rc = ERR_PROG_ERROR;
 112        }
 113        if (state & MCFCFM_USTAT_PVIOL)
 114        {
 115                debug ("%s(): CFM protection violation",__FUNCTION__);
 116                rc = ERR_PROTECTED;
 117        }
 118        if (checkblank)
 119        {
 120                if (!(state & MCFCFM_USTAT_BLANK))
 121                {
 122                        debug ("%s(): CFM erras error",__FUNCTION__);
 123                        rc = ERR_NOT_ERASED;
 124                }
 125        }
 126        MCFCFM_USTAT = state & 0x34; /* reset state */
 127        return rc;
 128}
 129
 130/* Erase 16KiB = 8 2KiB pages */
 131
 132int cfm_flash_erase_sector (flash_info_t * info, int sector)
 133{
 134        ulong address;
 135        int page;
 136        int rc;
 137        rc= ERR_OK;
 138        address = cmf_backdoor_address(info->start[sector]);
 139        for (page=0; (page<8) && (rc==ERR_OK); page++)
 140        {
 141                *(volatile __u32*) address = 0;
 142                MCFCFM_CMD = MCFCFM_CMD_PGERS;
 143                MCFCFM_USTAT = MCFCFM_USTAT_CBEIF;
 144                rc = cfm_flash_readycheck(0);
 145                if (rc==ERR_OK)
 146                {
 147                        *(volatile __u32*) address = 0;
 148                        MCFCFM_CMD = MCFCFM_CMD_PGERSVER;
 149                        MCFCFM_USTAT = MCFCFM_USTAT_CBEIF;
 150                        rc = cfm_flash_readycheck(1);
 151                }
 152                address += 0x800;
 153        }
 154        return rc;
 155}
 156
 157int cfm_flash_write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 158{
 159        int rc;
 160        ulong dest, data;
 161
 162        rc = ERR_OK;
 163        if (addr & 3)
 164        {
 165                debug ("Byte and Word alignment not supported\n");
 166                rc = ERR_ALIGN;
 167        }
 168        if (cnt & 3)
 169        {
 170                debug ("Byte and Word transfer not supported\n");
 171                rc = ERR_ALIGN;
 172        }
 173        dest = cmf_backdoor_address(addr);
 174        while ((cnt>=4) && (rc == ERR_OK))
 175        {
 176                data = *((volatile u32 *) src);
 177                *(volatile u32*) dest = data;
 178                MCFCFM_CMD = MCFCFM_CMD_PGM;
 179                MCFCFM_USTAT = MCFCFM_USTAT_CBEIF;
 180                rc = cfm_flash_readycheck(0);
 181                if (*(volatile u32*) addr != data) rc = ERR_PROG_ERROR;
 182                src +=4;
 183                dest +=4;
 184                addr +=4;
 185                cnt -=4;
 186        }
 187        return rc;
 188}
 189
 190#ifdef CONFIG_SYS_FLASH_PROTECTION
 191
 192int cfm_flash_protect(flash_info_t * info,long sector,int prot)
 193{
 194        int rc;
 195
 196        rc= ERR_OK;
 197        if (prot)
 198        {
 199                MCFCFM_PROT |= (1<<sector);
 200                info->protect[sector]=1;
 201        }
 202        else
 203        {
 204                MCFCFM_PROT &= ~(1<<sector);
 205                info->protect[sector]=0;
 206        }
 207        return rc;
 208}
 209
 210#endif
 211
 212#endif
 213