aboutsummaryrefslogtreecommitdiffstats
path: root/target/Config.in
blob: 7f07ff0ac102923a5e6876a3667533a13c181a24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
choice
	prompt "Target System"
	default LINUX_2_4_BRCM
	
config LINUX_2_6_ARUBA
	bool "Aruba [2.6]"
	select mips
	select LINUX_2_6
	select PCI_SUPPORT
	help
          Build firmware images for Aruba boards 

config LINUX_2_4_AR531X
	bool "Atheros AR531x [2.4]"
	select mips
	select LINUX_2_4
	help
	  Build firmware images for Atheros AR531x based boards
	  (e.g. Netgear WGT624, Linksys WRT55AG)

config LINUX_2_4_BRCM
	bool "Broadcom BCM47xx/53xx [2.4]"
	select mipsel
	select PCI_SUPPORT
	select PCMCIA_SUPPORT
	help
	  Build firmware images for Broadcom based routers
	  (e.g. Linksys WRT54G(S), Asus WL-500g, Motorola WR850G)
	  
	  This one builds the generic .trx images, activate one of the
	  options below for creating device specific files for use 
	  with TFTP client too. 

config LINUX_2_6_BRCM
	bool "Broadcom BCM47xx/53xx [2.6]"
	select mipsel
	select LINUX_2_6
	select PCI_SUPPORT
	#select PCMCIA_SUPPORT
	help
	  Build firmware images for Broadcom based routers
	  (e.g. Netgear WGT634u)

config LINUX_2_4_AR7
	bool "TI AR7 [2.4]"
	select mipsel
	help
	  Build firmware images for TI AR7 based routers (w.g. Linksys WAG54G v2)

config LINUX_2_4_X86
	bool "x86 [2.4]"
	select i386
	select LINUX_2_4
	select PCMCIA_SUPPORT
	help
	  Build firmware images for x86 based boards
	  (e.g. Soekris net4521 and net4801, PC Engines WRAP...)

config LINUX_2_6_X86
	bool "x86 [2.6]"
	select i386
	select LINUX_2_6
	select PCMCIA_SUPPORT
	help
	  Build firmware images for x86 based boards
	  (e.g. Soekris net4521 and net4801, PC Engines WRAP...)

config LINUX_2_6_AU1000
	bool "au1000 [2.6]"
	select mipsel
	select LINUX_2_6
	select PCMCIA_SUPPORT
	help
	  Build firmware for AMD Alchemy 1500 boards
	  (e.g. 4G-Systems Mesh/Access Cube ...)

if CONFIG_DEVEL

config LINUX_2_6_ARM
	bool "UNSUPPORTED little-endian arm platform"
	select LINUX_2_6
	select arm

config LINUX_2_6_ARMEB
	bool "UNSUPPORTED big-endian arm platform"
	select LINUX_2_6
	select armeb

config LINUX_2_6_CRIS
	bool "UNSUPPORTED cris platform"
	select LINUX_2_6
	select cris

config LINUX_2_6_M68K
	bool "UNSUPPORTED m68k platform"
	select LINUX_2_6
	select m68k

config LINUX_2_6_PPC
	bool "UNSUPPORTED powerpc platform"
	select LINUX_2_6
	select powerpc

config LINUX_2_6_SH3
	bool "UNSUPPORTED little-endian sh3 platform"
	select LINUX_2_6
	select sh3

config LINUX_2_6_SH3EB
	bool "UNSUPPORTED big-endian sh3 platform"
	select LINUX_2_6
	select sh3eb

config LINUX_2_6_SH4
	bool "UNSUPPORTED little-endian sh4 platform"
	select LINUX_2_6
	select sh4

config LINUX_2_6_SH4EB
	bool "UNSUPPORTED big-endian sh4 platform"
	select LINUX_2_6
	select sh4eb

config LINUX_2_6_SPARC
	bool "UNSUPPORTED sparc platform"
	select LINUX_2_6
	select sparc

endif

endchoice


# Kernel/Hardware features

config LINUX_2_4
	bool

config LINUX_2_6
	bool

config PCI_SUPPORT
	bool

config PCMCIA_SUPPORT
	bool


# Architecture selection

config i386
	bool
	
config mips
	bool

config mipsel
	bool

config arm
	bool

config armeb
	bool

config cris
	bool

config m68k
	bool

config powerpc
	bool

config sh3
	bool

config sh3eb
	bool

config sh4
	bool

config sh4eb
	bool

config sparc
	bool

config ARCH
	string
	default "arm"     if arm
	default "armeb"   if armeb
	default "cris"    if cris
	default "i386"    if i386
	default "m68k"    if m68k
	default "mips"    if mips
	default "mipsel"  if mipsel || !CONFIG_DEVEL
	default "powerpc" if powerpc
	default "sh3"     if sh3
	default "sh3eb"   if sh3eb
	default "sh4"     if sh4
	default "sh4eb"   if sh4eb
	default "sparc"   if sparc
pan class="gi">+ + if (!len) + return 0; + + if ((offset + len) > cc->sflash.size) + return -EINVAL; + + if ((len >= 4) && (offset & 3)) + cnt = 4 - (offset & 3); + else if ((len >= 4) && ((u32)buf & 3)) + cnt = 4 - ((u32)buf & 3); + else + cnt = len; + + from = (u8 *)KSEG0ADDR(BCMA_SOC_FLASH2 + offset); + + to = (u8 *)buf; + + if (cnt < 4) { + for (i = 0; i < cnt; i++) { + *to = readb(from); + from++; + to++; + } + return cnt; + } + + while (cnt >= 4) { + *(u32 *)to = readl(from); + from += 4; + to += 4; + cnt -= 4; + } + + return len - cnt; +} + +/* Poll for command completion. Returns zero when complete. */ +static int bcma_sflash_poll(struct bcm47xx_sflash *dev, u32 offset) +{ + struct bcma_drv_cc *cc = dev->bcc; + + if (offset >= cc->sflash.size) + return -22; + + switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { + case BCMA_CC_FLASHT_STSER: + /* Check for ST Write In Progress bit */ + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_RDSR); + return bcma_cc_read32(cc, BCMA_CC_FLASHDATA) + & BCMA_CC_FLASHDATA_ST_WIP; + case BCMA_CC_FLASHT_ATSER: + /* Check for Atmel Ready bit */ + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_STATUS); + return !(bcma_cc_read32(cc, BCMA_CC_FLASHDATA) + & BCMA_CC_FLASHDATA_AT_READY); + } + + return 0; +} + + +static int sflash_st_write(struct bcm47xx_sflash *dev, u32 offset, u32 len, + const u8 *buf) +{ + int written = 1; + struct bcma_drv_cc *cc = dev->bcc; + + /* Enable writes */ + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_WREN); + bcma_sflash_write_u8(cc, offset, *buf++); + /* Issue a page program with CSA bit set */ + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_CSA | BCMA_CC_FLASHCTL_ST_PP); + offset++; + len--; + while (len > 0) { + if ((offset & 255) == 0) { + /* Page boundary, poll droping cs and return */ + bcma_cc_write32(cc, BCMA_CC_FLASHCTL, 0); + udelay(1); + if (!bcma_sflash_poll(dev, offset)) { + /* Flash rejected command */ + return -EAGAIN; + } + return written; + } else { + /* Write single byte */ + bcma_sflash_cmd(cc, + BCMA_CC_FLASHCTL_ST_CSA | + *buf++); + } + written++; + offset++; + len--; + } + /* All done, drop cs & poll */ + bcma_cc_write32(cc, BCMA_CC_FLASHCTL, 0); + udelay(1); + if (!bcma_sflash_poll(dev, offset)) { + /* Flash rejected command */ + return -EAGAIN; + } + return written; +} + +static int sflash_at_write(struct bcm47xx_sflash *dev, u32 offset, u32 len, + const u8 *buf) +{ + struct bcma_drv_cc *cc = dev->bcc; + u32 page, byte, mask; + int ret = 0; + + mask = dev->blocksize - 1; + page = (offset & ~mask) << 1; + byte = offset & mask; + /* Read main memory page into buffer 1 */ + if (byte || (len < dev->blocksize)) { + int i = 100; + bcma_cc_write32(cc, BCMA_CC_FLASHADDR, page); + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_BUF1_LOAD); + /* 250 us for AT45DB321B */ + while (i > 0 && bcma_sflash_poll(dev, offset)) { + udelay(10); + i--; + } + BUG_ON(!bcma_sflash_poll(dev, offset)); + } + /* Write into buffer 1 */ + for (ret = 0; (ret < (int)len) && (byte < dev->blocksize); ret++) { + bcma_sflash_write_u8(cc, byte++, *buf++); + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_BUF1_WRITE); + } + /* Write buffer 1 into main memory page */ + bcma_cc_write32(cc, BCMA_CC_FLASHADDR, page); + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_BUF1_PROGRAM); + + return ret; +} + +/* Write len bytes starting at offset into buf. Returns number of bytes + * written. Caller should poll for completion. + */ +static int bcma_sflash_write(struct bcm47xx_sflash *dev, u32 offset, u32 len, + const u8 *buf) +{ + int ret = 0, tries = NUM_RETRIES; + struct bcma_drv_cc *cc = dev->bcc; + + if (!len) + return 0; + + if ((offset + len) > cc->sflash.size) + return -EINVAL; + + switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { + case BCMA_CC_FLASHT_STSER: + do { + ret = sflash_st_write(dev, offset, len, buf); + tries--; + } while (ret == -EAGAIN && tries > 0); + + if (ret == -EAGAIN && tries == 0) { + bcma_info(cc->core->bus, "ST Flash rejected write\n"); + ret = -EIO; + } + break; + case BCMA_CC_FLASHT_ATSER: + ret = sflash_at_write(dev, offset, len, buf); + break; + } + + return ret; +} + +/* Erase a region. Returns number of bytes scheduled for erasure. + * Caller should poll for completion. + */ +static int bcma_sflash_erase(struct bcm47xx_sflash *dev, u32 offset) +{ + struct bcma_drv_cc *cc = dev->bcc; + + if (offset >= cc->sflash.size) + return -EINVAL; + + switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { + case BCMA_CC_FLASHT_STSER: + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_WREN); + bcma_cc_write32(cc, BCMA_CC_FLASHADDR, offset); + /* Newer flashes have "sub-sectors" which can be erased independently + * with a new command: ST_SSE. The ST_SE command erases 64KB just as + * before. + */ + if (dev->blocksize < (64 * 1024)) + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_SSE); + else + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_SE); + return dev->blocksize; + case BCMA_CC_FLASHT_ATSER: + bcma_cc_write32(cc, BCMA_CC_FLASHADDR, offset << 1); + bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_PAGE_ERASE); + return dev->blocksize; + } + + return 0; +} + /* Initialize serial flash access */ int bcma_sflash_init(struct bcma_drv_cc *cc) { struct bcma_bus *bus = cc->core->bus; - struct bcma_sflash *sflash = &cc->sflash; - struct bcma_sflash_tbl_e *e; + struct bcm47xx_sflash *sflash = &cc->sflash; + const struct bcma_sflash_tbl_e *e; u32 id, id2; switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { @@ -150,6 +375,12 @@ int bcma_sflash_init(struct bcma_drv_cc sflash->numblocks = e->numblocks; sflash->size = sflash->blocksize * sflash->numblocks; sflash->present = true; + sflash->read = bcma_sflash_read; + sflash->poll = bcma_sflash_poll; + sflash->write = bcma_sflash_write; + sflash->erase = bcma_sflash_erase; + sflash->type = BCM47XX_SFLASH_BCMA; + sflash->bcc = cc; bcma_info(bus, "Found %s serial flash (size: %dKiB, blocksize: 0x%X, blocks: %d)\n", e->name, sflash->size / 1024, sflash->blocksize, --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -3,6 +3,8 @@ #include <linux/platform_device.h> +#include <linux/mtd/bcm47xx_sflash.h> + /** ChipCommon core registers. **/ #define BCMA_CC_ID 0x0000 #define BCMA_CC_ID_ID 0x0000FFFF @@ -518,17 +520,6 @@ struct bcma_pflash { u32 window_size; }; -#ifdef CONFIG_BCMA_SFLASH -struct bcma_sflash { - bool present; - u32 window; - u32 blocksize; - u16 numblocks; - u32 size; - - struct mtd_info *mtd; -}; -#endif #ifdef CONFIG_BCMA_NFLASH struct mtd_info; @@ -563,7 +554,7 @@ struct bcma_drv_cc { #ifdef CONFIG_BCMA_DRIVER_MIPS struct bcma_pflash pflash; #ifdef CONFIG_BCMA_SFLASH - struct bcma_sflash sflash; + struct bcm47xx_sflash sflash; #endif #ifdef CONFIG_BCMA_NFLASH struct bcma_nflash nflash;