]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/amcc/walnut/flash.c
Merge git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / board / amcc / walnut / flash.c
1 /*
2  * (C) Copyright 2000-2005
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /*
9  * Modified 4/5/2001
10  * Wait for completion of each sector erase command issued
11  * 4/5/2001
12  * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
13  */
14
15 #include <common.h>
16 #include <asm/ppc4xx.h>
17 #include <asm/processor.h>
18
19 #undef DEBUG
20 #ifdef DEBUG
21 #define DEBUGF(x...) printf(x)
22 #else
23 #define DEBUGF(x...)
24 #endif                          /* DEBUG */
25
26 /*
27  * include common flash code (for amcc boards)
28  */
29 #include "../common/flash.c"
30
31 /*-----------------------------------------------------------------------
32  * Functions
33  */
34 static ulong flash_get_size(vu_long * addr, flash_info_t * info);
35 static void flash_get_offsets(ulong base, flash_info_t * info);
36
37 unsigned long flash_init(void)
38 {
39         unsigned long size_b0, size_b1;
40         int i;
41         uint pbcr;
42         unsigned long base_b0, base_b1;
43
44         /* Init: no FLASHes known */
45         for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
46                 flash_info[i].flash_id = FLASH_UNKNOWN;
47         }
48
49         /* Static FLASH Bank configuration here - FIXME XXX */
50
51         size_b0 =
52             flash_get_size((vu_long *) FLASH_BASE0_PRELIM, &flash_info[0]);
53
54         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
55                 printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
56                        size_b0, size_b0 << 20);
57         }
58
59         /* Only one bank */
60         if (CONFIG_SYS_MAX_FLASH_BANKS == 1) {
61                 /* Setup offsets */
62                 flash_get_offsets(FLASH_BASE0_PRELIM, &flash_info[0]);
63
64                 /* Monitor protection ON by default */
65                 (void)flash_protect(FLAG_PROTECT_SET,
66                                     CONFIG_SYS_MONITOR_BASE,
67                                     CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN - 1,
68                                     &flash_info[0]);
69 #ifdef CONFIG_ENV_IS_IN_FLASH
70                 (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
71                                     CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
72                                     &flash_info[0]);
73                 (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
74                                     CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
75                                     &flash_info[0]);
76 #endif
77
78                 size_b1 = 0;
79                 flash_info[0].size = size_b0;
80         } else {
81                 /* 2 banks */
82                 size_b1 =
83                     flash_get_size((vu_long *) FLASH_BASE1_PRELIM,
84                                    &flash_info[1]);
85
86                 /* Re-do sizing to get full correct info */
87
88                 if (size_b1) {
89                         mtdcr(EBC0_CFGADDR, PB0CR);
90                         pbcr = mfdcr(EBC0_CFGDATA);
91                         mtdcr(EBC0_CFGADDR, PB0CR);
92                         base_b1 = -size_b1;
93                         pbcr =
94                             (pbcr & 0x0001ffff) | base_b1 |
95                             (((size_b1 / 1024 / 1024) - 1) << 17);
96                         mtdcr(EBC0_CFGDATA, pbcr);
97                         /*          printf("PB1CR = %x\n", pbcr); */
98                 }
99
100                 if (size_b0) {
101                         mtdcr(EBC0_CFGADDR, PB1CR);
102                         pbcr = mfdcr(EBC0_CFGDATA);
103                         mtdcr(EBC0_CFGADDR, PB1CR);
104                         base_b0 = base_b1 - size_b0;
105                         pbcr =
106                             (pbcr & 0x0001ffff) | base_b0 |
107                             (((size_b0 / 1024 / 1024) - 1) << 17);
108                         mtdcr(EBC0_CFGDATA, pbcr);
109                         /*            printf("PB0CR = %x\n", pbcr); */
110                 }
111
112                 size_b0 = flash_get_size((vu_long *) base_b0, &flash_info[0]);
113
114                 flash_get_offsets(base_b0, &flash_info[0]);
115
116                 /* monitor protection ON by default */
117                 (void)flash_protect(FLAG_PROTECT_SET,
118                                     base_b0 + size_b0 - monitor_flash_len,
119                                     base_b0 + size_b0 - 1, &flash_info[0]);
120
121                 if (size_b1) {
122                         /* Re-do sizing to get full correct info */
123                         size_b1 =
124                             flash_get_size((vu_long *) base_b1, &flash_info[1]);
125
126                         flash_get_offsets(base_b1, &flash_info[1]);
127
128                         /* monitor protection ON by default */
129                         (void)flash_protect(FLAG_PROTECT_SET,
130                                             base_b1 + size_b1 -
131                                             monitor_flash_len,
132                                             base_b1 + size_b1 - 1,
133                                             &flash_info[1]);
134                         /* monitor protection OFF by default (one is enough) */
135                         (void)flash_protect(FLAG_PROTECT_CLEAR,
136                                             base_b0 + size_b0 -
137                                             monitor_flash_len,
138                                             base_b0 + size_b0 - 1,
139                                             &flash_info[0]);
140                 } else {
141                         flash_info[1].flash_id = FLASH_UNKNOWN;
142                         flash_info[1].sector_count = -1;
143                 }
144
145                 flash_info[0].size = size_b0;
146                 flash_info[1].size = size_b1;
147         }                       /* else 2 banks */
148         return (size_b0 + size_b1);
149 }
150
151
152 static void flash_get_offsets(ulong base, flash_info_t * info)
153 {
154         int i;
155
156         /* set up sector start address table */
157         if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
158             (info->flash_id == FLASH_AM040)) {
159                 for (i = 0; i < info->sector_count; i++)
160                         info->start[i] = base + (i * 0x00010000);
161         } else {
162                 if (info->flash_id & FLASH_BTYPE) {
163                         /* set sector offsets for bottom boot block type        */
164                         info->start[0] = base + 0x00000000;
165                         info->start[1] = base + 0x00004000;
166                         info->start[2] = base + 0x00006000;
167                         info->start[3] = base + 0x00008000;
168                         for (i = 4; i < info->sector_count; i++) {
169                                 info->start[i] =
170                                     base + (i * 0x00010000) - 0x00030000;
171                         }
172                 } else {
173                         /* set sector offsets for top boot block type           */
174                         i = info->sector_count - 1;
175                         info->start[i--] = base + info->size - 0x00004000;
176                         info->start[i--] = base + info->size - 0x00006000;
177                         info->start[i--] = base + info->size - 0x00008000;
178                         for (; i >= 0; i--) {
179                                 info->start[i] = base + i * 0x00010000;
180                         }
181                 }
182         }
183 }