123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- /*
- * Basic Flash Driver for Freescale MCF 5281/5282 internal FLASH
- *
- * (C) Copyright 2005 BuS Elektronik GmbH & Co.KG <esw@bus-elektonik.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
- #include <common.h>
- #include <asm/m5282.h>
- #include "cfm_flash.h"
- #if defined(CONFIG_M5281) || defined(CONFIG_M5282)
- #if (CFG_CLK>20000000)
- #define CFM_CLK (((long) CFG_CLK / (400000 * 8) + 1) | 0x40)
- #else
- #define CFM_CLK ((long) CFG_CLK / 400000 + 1)
- #endif
- #define cmf_backdoor_address(addr) (((addr) & 0x0007FFFF) | 0x04000000 | \
- (CFG_MBAR & 0xC0000000))
- void cfm_flash_print_info (flash_info_t * info)
- {
- printf ("Freescale: ");
- switch (info->flash_id & FLASH_TYPEMASK) {
- case FREESCALE_ID_MCF5281 & FLASH_TYPEMASK:
- printf ("MCF5281 internal FLASH\n");
- break;
- case FREESCALE_ID_MCF5282 & FLASH_TYPEMASK:
- printf ("MCF5282 internal FLASH\n");
- break;
- default:
- printf ("Unknown Chip Type\n");
- break;
- }
- }
- void cfm_flash_init (flash_info_t * info)
- {
- int sector;
- ulong protection;
- MCFCFM_MCR = 0;
- MCFCFM_CLKD = CFM_CLK;
- debug ("CFM Clock divider: %ld (%d Hz @ %ld Hz)\n",CFM_CLK,\
- CFG_CLK / (2* ((CFM_CLK & 0x3F)+1) * (1+((CFM_CLK & 0x40)>>6)*7)),\
- CFG_CLK);
- MCFCFM_SACC = 0;
- MCFCFM_DACC = 0;
- if (MCFCFM_SEC & MCFCFM_SEC_KEYEN)
- puts("CFM backdoor access is enabled\n");
- if (MCFCFM_SEC & MCFCFM_SEC_SECSTAT)
- puts("CFM securety is enabled\n");
- #ifdef CONFIG_M5281
- info->flash_id = (FREESCALE_MANUFACT & FLASH_VENDMASK) |
- (FREESCALE_ID_MCF5281 & FLASH_TYPEMASK);
- info->size = 256*1024;
- info->sector_count = 16;
- #else
- info->flash_id = (FREESCALE_MANUFACT & FLASH_VENDMASK) |
- (FREESCALE_ID_MCF5282 & FLASH_TYPEMASK);
- info->size = 512*1024;
- info->sector_count = 32;
- #endif
- protection = MCFCFM_PROT;
- for (sector = 0; sector < info->sector_count; sector++)
- {
- if (sector == 0)
- {
- info->start[sector] = CFG_INT_FLASH_BASE;
- }
- else
- {
- info->start[sector] = info->start[sector-1] + 0x04000;
- }
- info->protect[sector] = protection & 1;
- protection >>= 1;
- }
- }
- int cfm_flash_readycheck(int checkblank)
- {
- int rc;
- unsigned char state;
- rc = ERR_OK;
- while (!(MCFCFM_USTAT & MCFCFM_USTAT_CCIF));
- state = MCFCFM_USTAT;
- if (state & MCFCFM_USTAT_ACCERR)
- {
- debug ("%s(): CFM access error",__FUNCTION__);
- rc = ERR_PROG_ERROR;
- }
- if (state & MCFCFM_USTAT_PVIOL)
- {
- debug ("%s(): CFM protection violation",__FUNCTION__);
- rc = ERR_PROTECTED;
- }
- if (checkblank)
- {
- if (!(state & MCFCFM_USTAT_BLANK))
- {
- debug ("%s(): CFM erras error",__FUNCTION__);
- rc = ERR_NOT_ERASED;
- }
- }
- MCFCFM_USTAT = state & 0x34; /* reset state */
- return rc;
- }
- /* Erase 16KiB = 8 2KiB pages */
- int cfm_flash_erase_sector (flash_info_t * info, int sector)
- {
- ulong address;
- int page;
- int rc;
- rc= ERR_OK;
- address = cmf_backdoor_address(info->start[sector]);
- for (page=0; (page<8) && (rc==ERR_OK); page++)
- {
- *(volatile __u32*) address = 0;
- MCFCFM_CMD = MCFCFM_CMD_PGERS;
- MCFCFM_USTAT = MCFCFM_USTAT_CBEIF;
- rc = cfm_flash_readycheck(0);
- if (rc==ERR_OK)
- {
- *(volatile __u32*) address = 0;
- MCFCFM_CMD = MCFCFM_CMD_PGERSVER;
- MCFCFM_USTAT = MCFCFM_USTAT_CBEIF;
- rc = cfm_flash_readycheck(1);
- }
- address += 0x800;
- }
- return rc;
- }
- int cfm_flash_write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
- {
- int rc;
- ulong dest, data;
- rc = ERR_OK;
- if (addr & 3)
- {
- debug ("Byte and Word alignment not supported\n");
- rc = ERR_ALIGN;
- }
- if (cnt & 3)
- {
- debug ("Byte and Word transfer not supported\n");
- rc = ERR_ALIGN;
- }
- dest = cmf_backdoor_address(addr);
- while ((cnt>=4) && (rc == ERR_OK))
- {
- data =*((volatile u32 *) src);
- *(volatile u32*) dest = data;
- MCFCFM_CMD = MCFCFM_CMD_PGM;
- MCFCFM_USTAT = MCFCFM_USTAT_CBEIF;
- rc = cfm_flash_readycheck(0);
- if (*(volatile u32*) addr != data) rc = ERR_PROG_ERROR;
- src +=4;
- dest +=4;
- addr +=4;
- cnt -=4;
- }
- return rc;
- }
- #ifdef CFG_FLASH_PROTECTION
- int cfm_flash_protect(flash_info_t * info,long sector,int prot)
- {
- int rc;
- rc= ERR_OK;
- if (prot)
- {
- MCFCFM_PROT |= (1<<sector);
- info->protect[sector]=1;
- }
- else
- {
- MCFCFM_PROT &= ~(1<<sector);
- info->protect[sector]=0;
- }
- return rc;
- }
- #endif
- #endif
|