~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/board/amcc/bubinga/flash.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2000
 
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
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];    /* info for FLASH chips        */
 
20
 
 
21
#undef DEBUG
 
22
#ifdef DEBUG
 
23
#define DEBUGF(x...) printf(x)
 
24
#else
 
25
#define DEBUGF(x...)
 
26
#endif                          /* DEBUG */
 
27
 
 
28
/*
 
29
 * include common flash code (for amcc boards)
 
30
 */
 
31
#include "../common/flash.c"
 
32
 
 
33
/*-----------------------------------------------------------------------
 
34
 * Functions
 
35
 */
 
36
static ulong flash_get_size(vu_long * addr, flash_info_t * info);
 
37
static void flash_get_offsets(ulong base, flash_info_t * info);
 
38
 
 
39
unsigned long flash_init(void)
 
40
{
 
41
        unsigned long size_b0, size_b1;
 
42
        int i;
 
43
        uint pbcr;
 
44
        unsigned long base_b0, base_b1;
 
45
 
 
46
        /* Init: no FLASHes known */
 
47
        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
 
48
                flash_info[i].flash_id = FLASH_UNKNOWN;
 
49
        }
 
50
 
 
51
        /* Static FLASH Bank configuration here - FIXME XXX */
 
52
 
 
53
        size_b0 =
 
54
            flash_get_size((vu_long *) FLASH_BASE0_PRELIM, &flash_info[0]);
 
55
 
 
56
        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
 
57
                printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
 
58
                       size_b0, size_b0 << 20);
 
59
        }
 
60
 
 
61
        /* Only one bank */
 
62
        if (CONFIG_SYS_MAX_FLASH_BANKS == 1) {
 
63
                /* Setup offsets */
 
64
                flash_get_offsets(FLASH_BASE0_PRELIM, &flash_info[0]);
 
65
 
 
66
                /* Monitor protection ON by default */
 
67
                (void)flash_protect(FLAG_PROTECT_SET,
 
68
                                    CONFIG_SYS_MONITOR_BASE,
 
69
                                    CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN - 1,
 
70
                                    &flash_info[0]);
 
71
#ifdef CONFIG_ENV_IS_IN_FLASH
 
72
                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
 
73
                                    CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
 
74
                                    &flash_info[0]);
 
75
                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
 
76
                                    CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
 
77
                                    &flash_info[0]);
 
78
#endif
 
79
 
 
80
                size_b1 = 0;
 
81
                flash_info[0].size = size_b0;
 
82
        }
 
83
 
 
84
        /* 2 banks */
 
85
        else {
 
86
                size_b1 =
 
87
                    flash_get_size((vu_long *) FLASH_BASE1_PRELIM,
 
88
                                   &flash_info[1]);
 
89
 
 
90
                /* Re-do sizing to get full correct info */
 
91
 
 
92
                if (size_b1) {
 
93
                        mtdcr(EBC0_CFGADDR, PB0CR);
 
94
                        pbcr = mfdcr(EBC0_CFGDATA);
 
95
                        mtdcr(EBC0_CFGADDR, PB0CR);
 
96
                        base_b1 = -size_b1;
 
97
                        pbcr = (pbcr & 0x0001ffff) | base_b1 |
 
98
                            (((size_b1 / 1024 / 1024) - 1) << 17);
 
99
                        mtdcr(EBC0_CFGDATA, pbcr);
 
100
                        /*          printf("PB1CR = %x\n", pbcr); */
 
101
                }
 
102
 
 
103
                if (size_b0) {
 
104
                        mtdcr(EBC0_CFGADDR, PB1CR);
 
105
                        pbcr = mfdcr(EBC0_CFGDATA);
 
106
                        mtdcr(EBC0_CFGADDR, PB1CR);
 
107
                        base_b0 = base_b1 - size_b0;
 
108
                        pbcr = (pbcr & 0x0001ffff) | base_b0 |
 
109
                            (((size_b0 / 1024 / 1024) - 1) << 17);
 
110
                        mtdcr(EBC0_CFGDATA, pbcr);
 
111
                        /*            printf("PB0CR = %x\n", pbcr); */
 
112
                }
 
113
 
 
114
                size_b0 = flash_get_size((vu_long *) base_b0, &flash_info[0]);
 
115
 
 
116
                flash_get_offsets(base_b0, &flash_info[0]);
 
117
 
 
118
                /* monitor protection ON by default */
 
119
                (void)flash_protect(FLAG_PROTECT_SET,
 
120
                                    base_b0 + size_b0 - CONFIG_SYS_MONITOR_LEN,
 
121
                                    base_b0 + size_b0 - 1, &flash_info[0]);
 
122
                /* Also protect sector containing initial power-up instruction */
 
123
                /* (flash_protect() checks address range - other call ignored) */
 
124
                (void)flash_protect(FLAG_PROTECT_SET,
 
125
                                    0xFFFFFFFC, 0xFFFFFFFF, &flash_info[0]);
 
126
                (void)flash_protect(FLAG_PROTECT_SET,
 
127
                                    0xFFFFFFFC, 0xFFFFFFFF, &flash_info[1]);
 
128
 
 
129
                if (size_b1) {
 
130
                        /* Re-do sizing to get full correct info */
 
131
                        size_b1 =
 
132
                            flash_get_size((vu_long *) base_b1, &flash_info[1]);
 
133
 
 
134
                        flash_get_offsets(base_b1, &flash_info[1]);
 
135
 
 
136
                        /* monitor protection ON by default */
 
137
                        (void)flash_protect(FLAG_PROTECT_SET,
 
138
                                            base_b1 + size_b1 - CONFIG_SYS_MONITOR_LEN,
 
139
                                            base_b1 + size_b1 - 1,
 
140
                                            &flash_info[1]);
 
141
                        /* monitor protection OFF by default (one is enough) */
 
142
                        (void)flash_protect(FLAG_PROTECT_CLEAR,
 
143
                                            base_b0 + size_b0 - CONFIG_SYS_MONITOR_LEN,
 
144
                                            base_b0 + size_b0 - 1,
 
145
                                            &flash_info[0]);
 
146
                } else {
 
147
                        flash_info[1].flash_id = FLASH_UNKNOWN;
 
148
                        flash_info[1].sector_count = -1;
 
149
                }
 
150
 
 
151
                flash_info[0].size = size_b0;
 
152
                flash_info[1].size = size_b1;
 
153
        }                       /* else 2 banks */
 
154
        return (size_b0 + size_b1);
 
155
}
 
156
 
 
157
static void flash_get_offsets(ulong base, flash_info_t * info)
 
158
{
 
159
        int i;
 
160
 
 
161
        /* set up sector start address table */
 
162
        if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
 
163
            (info->flash_id == FLASH_AM040)) {
 
164
                for (i = 0; i < info->sector_count; i++)
 
165
                        info->start[i] = base + (i * 0x00010000);
 
166
        } else {
 
167
                if (info->flash_id & FLASH_BTYPE) {
 
168
                        /* set sector offsets for bottom boot block type        */
 
169
                        info->start[0] = base + 0x00000000;
 
170
                        info->start[1] = base + 0x00004000;
 
171
                        info->start[2] = base + 0x00006000;
 
172
                        info->start[3] = base + 0x00008000;
 
173
                        for (i = 4; i < info->sector_count; i++) {
 
174
                                info->start[i] =
 
175
                                    base + (i * 0x00010000) - 0x00030000;
 
176
                        }
 
177
                } else {
 
178
                        /* set sector offsets for top boot block type           */
 
179
                        i = info->sector_count - 1;
 
180
                        info->start[i--] = base + info->size - 0x00004000;
 
181
                        info->start[i--] = base + info->size - 0x00006000;
 
182
                        info->start[i--] = base + info->size - 0x00008000;
 
183
                        for (; i >= 0; i--) {
 
184
                                info->start[i] = base + i * 0x00010000;
 
185
                        }
 
186
                }
 
187
        }
 
188
}