]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/BuS/EB+MCF-EV123/cfm_flash.c
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / board / BuS / EB+MCF-EV123 / cfm_flash.c
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
40 void 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
56 void 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
100 int 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
132 int 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
157 int 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
192 int 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