6cdfd2f730fd99eedffe2da4502a6be8f7c3c1a3
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-3.8 / 020-ssb_update.patch
1 --- a/drivers/ssb/Kconfig
2 +++ b/drivers/ssb/Kconfig
3 @@ -136,6 +136,11 @@ config SSB_DRIVER_MIPS
4
5 If unsure, say N
6
7 +config SSB_SFLASH
8 + bool "SSB serial flash support"
9 + depends on SSB_DRIVER_MIPS && BROKEN
10 + default y
11 +
12 # Assumption: We are on embedded, if we compile the MIPS core.
13 config SSB_EMBEDDED
14 bool
15 --- a/drivers/ssb/Makefile
16 +++ b/drivers/ssb/Makefile
17 @@ -11,6 +11,7 @@ ssb-$(CONFIG_SSB_SDIOHOST) += sdio.o
18 # built-in drivers
19 ssb-y += driver_chipcommon.o
20 ssb-y += driver_chipcommon_pmu.o
21 +ssb-$(CONFIG_SSB_SFLASH) += driver_chipcommon_sflash.o
22 ssb-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o
23 ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o
24 ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
25 --- /dev/null
26 +++ b/drivers/ssb/driver_chipcommon_sflash.c
27 @@ -0,0 +1,140 @@
28 +/*
29 + * Sonics Silicon Backplane
30 + * ChipCommon serial flash interface
31 + *
32 + * Licensed under the GNU/GPL. See COPYING for details.
33 + */
34 +
35 +#include <linux/ssb/ssb.h>
36 +
37 +#include "ssb_private.h"
38 +
39 +struct ssb_sflash_tbl_e {
40 + char *name;
41 + u32 id;
42 + u32 blocksize;
43 + u16 numblocks;
44 +};
45 +
46 +static struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = {
47 + { "M25P20", 0x11, 0x10000, 4, },
48 + { "M25P40", 0x12, 0x10000, 8, },
49 +
50 + { "M25P16", 0x14, 0x10000, 32, },
51 + { "M25P32", 0x15, 0x10000, 64, },
52 + { "M25P64", 0x16, 0x10000, 128, },
53 + { "M25FL128", 0x17, 0x10000, 256, },
54 + { 0 },
55 +};
56 +
57 +static struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = {
58 + { "SST25WF512", 1, 0x1000, 16, },
59 + { "SST25VF512", 0x48, 0x1000, 16, },
60 + { "SST25WF010", 2, 0x1000, 32, },
61 + { "SST25VF010", 0x49, 0x1000, 32, },
62 + { "SST25WF020", 3, 0x1000, 64, },
63 + { "SST25VF020", 0x43, 0x1000, 64, },
64 + { "SST25WF040", 4, 0x1000, 128, },
65 + { "SST25VF040", 0x44, 0x1000, 128, },
66 + { "SST25VF040B", 0x8d, 0x1000, 128, },
67 + { "SST25WF080", 5, 0x1000, 256, },
68 + { "SST25VF080B", 0x8e, 0x1000, 256, },
69 + { "SST25VF016", 0x41, 0x1000, 512, },
70 + { "SST25VF032", 0x4a, 0x1000, 1024, },
71 + { "SST25VF064", 0x4b, 0x1000, 2048, },
72 + { 0 },
73 +};
74 +
75 +static struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = {
76 + { "AT45DB011", 0xc, 256, 512, },
77 + { "AT45DB021", 0x14, 256, 1024, },
78 + { "AT45DB041", 0x1c, 256, 2048, },
79 + { "AT45DB081", 0x24, 256, 4096, },
80 + { "AT45DB161", 0x2c, 512, 4096, },
81 + { "AT45DB321", 0x34, 512, 8192, },
82 + { "AT45DB642", 0x3c, 1024, 8192, },
83 + { 0 },
84 +};
85 +
86 +static void ssb_sflash_cmd(struct ssb_chipcommon *cc, u32 opcode)
87 +{
88 + int i;
89 + chipco_write32(cc, SSB_CHIPCO_FLASHCTL,
90 + SSB_CHIPCO_FLASHCTL_START | opcode);
91 + for (i = 0; i < 1000; i++) {
92 + if (!(chipco_read32(cc, SSB_CHIPCO_FLASHCTL) &
93 + SSB_CHIPCO_FLASHCTL_BUSY))
94 + return;
95 + cpu_relax();
96 + }
97 + pr_err("SFLASH control command failed (timeout)!\n");
98 +}
99 +
100 +/* Initialize serial flash access */
101 +int ssb_sflash_init(struct ssb_chipcommon *cc)
102 +{
103 + struct ssb_sflash_tbl_e *e;
104 + u32 id, id2;
105 +
106 + switch (cc->capabilities & SSB_CHIPCO_CAP_FLASHT) {
107 + case SSB_CHIPCO_FLASHT_STSER:
108 + ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_DP);
109 +
110 + chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 0);
111 + ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES);
112 + id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA);
113 +
114 + chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 1);
115 + ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES);
116 + id2 = chipco_read32(cc, SSB_CHIPCO_FLASHDATA);
117 +
118 + switch (id) {
119 + case 0xbf:
120 + for (e = ssb_sflash_sst_tbl; e->name; e++) {
121 + if (e->id == id2)
122 + break;
123 + }
124 + break;
125 + case 0x13:
126 + return -ENOTSUPP;
127 + default:
128 + for (e = ssb_sflash_st_tbl; e->name; e++) {
129 + if (e->id == id)
130 + break;
131 + }
132 + break;
133 + }
134 + if (!e->name) {
135 + pr_err("Unsupported ST serial flash (id: 0x%X, id2: 0x%X)\n",
136 + id, id2);
137 + return -ENOTSUPP;
138 + }
139 +
140 + break;
141 + case SSB_CHIPCO_FLASHT_ATSER:
142 + ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_AT_STATUS);
143 + id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA) & 0x3c;
144 +
145 + for (e = ssb_sflash_at_tbl; e->name; e++) {
146 + if (e->id == id)
147 + break;
148 + }
149 + if (!e->name) {
150 + pr_err("Unsupported Atmel serial flash (id: 0x%X)\n",
151 + id);
152 + return -ENOTSUPP;
153 + }
154 +
155 + break;
156 + default:
157 + pr_err("Unsupported flash type\n");
158 + return -ENOTSUPP;
159 + }
160 +
161 + pr_info("Found %s serial flash (blocksize: 0x%X, blocks: %d)\n",
162 + e->name, e->blocksize, e->numblocks);
163 +
164 + pr_err("Serial flash support is not implemented yet!\n");
165 +
166 + return -ENOTSUPP;
167 +}
168 --- a/drivers/ssb/driver_gpio.c
169 +++ b/drivers/ssb/driver_gpio.c
170 @@ -74,6 +74,16 @@ static void ssb_gpio_chipco_free(struct
171 ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
172 }
173
174 +static int ssb_gpio_chipco_to_irq(struct gpio_chip *chip, unsigned gpio)
175 +{
176 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
177 +
178 + if (bus->bustype == SSB_BUSTYPE_SSB)
179 + return ssb_mips_irq(bus->chipco.dev) + 2;
180 + else
181 + return -EINVAL;
182 +}
183 +
184 static int ssb_gpio_chipco_init(struct ssb_bus *bus)
185 {
186 struct gpio_chip *chip = &bus->gpio;
187 @@ -86,6 +96,7 @@ static int ssb_gpio_chipco_init(struct s
188 chip->set = ssb_gpio_chipco_set_value;
189 chip->direction_input = ssb_gpio_chipco_direction_input;
190 chip->direction_output = ssb_gpio_chipco_direction_output;
191 + chip->to_irq = ssb_gpio_chipco_to_irq;
192 chip->ngpio = 16;
193 /* There is just one SoC in one device and its GPIO addresses should be
194 * deterministic to address them more easily. The other buses could get
195 @@ -134,6 +145,16 @@ static int ssb_gpio_extif_direction_outp
196 return 0;
197 }
198
199 +static int ssb_gpio_extif_to_irq(struct gpio_chip *chip, unsigned gpio)
200 +{
201 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
202 +
203 + if (bus->bustype == SSB_BUSTYPE_SSB)
204 + return ssb_mips_irq(bus->extif.dev) + 2;
205 + else
206 + return -EINVAL;
207 +}
208 +
209 static int ssb_gpio_extif_init(struct ssb_bus *bus)
210 {
211 struct gpio_chip *chip = &bus->gpio;
212 @@ -144,6 +165,7 @@ static int ssb_gpio_extif_init(struct ss
213 chip->set = ssb_gpio_extif_set_value;
214 chip->direction_input = ssb_gpio_extif_direction_input;
215 chip->direction_output = ssb_gpio_extif_direction_output;
216 + chip->to_irq = ssb_gpio_extif_to_irq;
217 chip->ngpio = 5;
218 /* There is just one SoC in one device and its GPIO addresses should be
219 * deterministic to address them more easily. The other buses could get
220 --- a/drivers/ssb/driver_mipscore.c
221 +++ b/drivers/ssb/driver_mipscore.c
222 @@ -10,6 +10,7 @@
223
224 #include <linux/ssb/ssb.h>
225
226 +#include <linux/mtd/physmap.h>
227 #include <linux/serial.h>
228 #include <linux/serial_core.h>
229 #include <linux/serial_reg.h>
230 @@ -17,6 +18,25 @@
231
232 #include "ssb_private.h"
233
234 +static const char *part_probes[] = { "bcm47xxpart", NULL };
235 +
236 +static struct physmap_flash_data ssb_pflash_data = {
237 + .part_probe_types = part_probes,
238 +};
239 +
240 +static struct resource ssb_pflash_resource = {
241 + .name = "ssb_pflash",
242 + .flags = IORESOURCE_MEM,
243 +};
244 +
245 +struct platform_device ssb_pflash_dev = {
246 + .name = "physmap-flash",
247 + .dev = {
248 + .platform_data = &ssb_pflash_data,
249 + },
250 + .resource = &ssb_pflash_resource,
251 + .num_resources = 1,
252 +};
253
254 static inline u32 mips_read32(struct ssb_mipscore *mcore,
255 u16 offset)
256 @@ -189,34 +209,43 @@ static void ssb_mips_serial_init(struct
257 static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
258 {
259 struct ssb_bus *bus = mcore->dev->bus;
260 + struct ssb_pflash *pflash = &mcore->pflash;
261
262 /* When there is no chipcommon on the bus there is 4MB flash */
263 if (!ssb_chipco_available(&bus->chipco)) {
264 - mcore->pflash.present = true;
265 - mcore->pflash.buswidth = 2;
266 - mcore->pflash.window = SSB_FLASH1;
267 - mcore->pflash.window_size = SSB_FLASH1_SZ;
268 - return;
269 + pflash->present = true;
270 + pflash->buswidth = 2;
271 + pflash->window = SSB_FLASH1;
272 + pflash->window_size = SSB_FLASH1_SZ;
273 + goto ssb_pflash;
274 }
275
276 /* There is ChipCommon, so use it to read info about flash */
277 switch (bus->chipco.capabilities & SSB_CHIPCO_CAP_FLASHT) {
278 case SSB_CHIPCO_FLASHT_STSER:
279 case SSB_CHIPCO_FLASHT_ATSER:
280 - pr_err("Serial flash not supported\n");
281 + pr_debug("Found serial flash\n");
282 + ssb_sflash_init(&bus->chipco);
283 break;
284 case SSB_CHIPCO_FLASHT_PARA:
285 pr_debug("Found parallel flash\n");
286 - mcore->pflash.present = true;
287 - mcore->pflash.window = SSB_FLASH2;
288 - mcore->pflash.window_size = SSB_FLASH2_SZ;
289 + pflash->present = true;
290 + pflash->window = SSB_FLASH2;
291 + pflash->window_size = SSB_FLASH2_SZ;
292 if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG)
293 & SSB_CHIPCO_CFG_DS16) == 0)
294 - mcore->pflash.buswidth = 1;
295 + pflash->buswidth = 1;
296 else
297 - mcore->pflash.buswidth = 2;
298 + pflash->buswidth = 2;
299 break;
300 }
301 +
302 +ssb_pflash:
303 + if (pflash->present) {
304 + ssb_pflash_data.width = pflash->buswidth;
305 + ssb_pflash_resource.start = pflash->window;
306 + ssb_pflash_resource.end = pflash->window + pflash->window_size;
307 + }
308 }
309
310 u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
311 --- a/drivers/ssb/main.c
312 +++ b/drivers/ssb/main.c
313 @@ -549,6 +549,14 @@ static int ssb_devices_register(struct s
314 dev_idx++;
315 }
316
317 +#ifdef CONFIG_SSB_DRIVER_MIPS
318 + if (bus->mipscore.pflash.present) {
319 + err = platform_device_register(&ssb_pflash_dev);
320 + if (err)
321 + pr_err("Error registering parallel flash\n");
322 + }
323 +#endif
324 +
325 return 0;
326 error:
327 /* Unwind the already registered devices. */
328 --- a/drivers/ssb/ssb_private.h
329 +++ b/drivers/ssb/ssb_private.h
330 @@ -217,6 +217,21 @@ extern u32 ssb_chipco_watchdog_timer_set
331 u32 ticks);
332 extern u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
333
334 +/* driver_chipcommon_sflash.c */
335 +#ifdef CONFIG_SSB_SFLASH
336 +int ssb_sflash_init(struct ssb_chipcommon *cc);
337 +#else
338 +static inline int ssb_sflash_init(struct ssb_chipcommon *cc)
339 +{
340 + pr_err("Serial flash not supported\n");
341 + return 0;
342 +}
343 +#endif /* CONFIG_SSB_SFLASH */
344 +
345 +#ifdef CONFIG_SSB_DRIVER_MIPS
346 +extern struct platform_device ssb_pflash_dev;
347 +#endif
348 +
349 #ifdef CONFIG_SSB_DRIVER_EXTIF
350 extern u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks);
351 extern u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
352 --- a/include/linux/ssb/ssb_driver_mips.h
353 +++ b/include/linux/ssb/ssb_driver_mips.h
354 @@ -45,6 +45,11 @@ void ssb_mipscore_init(struct ssb_mipsco
355 {
356 }
357
358 +static inline unsigned int ssb_mips_irq(struct ssb_device *dev)
359 +{
360 + return 0;
361 +}
362 +
363 #endif /* CONFIG_SSB_DRIVER_MIPS */
364
365 #endif /* LINUX_SSB_MIPSCORE_H_ */