[SSB]: add Sonics Silicon Backplane bus support
[safe/jmp/linux-2.6] / drivers / ssb / pci.c
1 /*
2  * Sonics Silicon Backplane PCI-Hostbus related functions.
3  *
4  * Copyright (C) 2005-2006 Michael Buesch <mb@bu3sch.de>
5  * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
6  * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
7  * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
8  * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
9  *
10  * Derived from the Broadcom 4400 device driver.
11  * Copyright (C) 2002 David S. Miller (davem@redhat.com)
12  * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
13  * Copyright (C) 2006 Broadcom Corporation.
14  *
15  * Licensed under the GNU/GPL. See COPYING for details.
16  */
17
18 #include <linux/ssb/ssb.h>
19 #include <linux/ssb/ssb_regs.h>
20 #include <linux/pci.h>
21 #include <linux/delay.h>
22
23 #include "ssb_private.h"
24
25
26 /* Define the following to 1 to enable a printk on each coreswitch. */
27 #define SSB_VERBOSE_PCICORESWITCH_DEBUG         0
28
29
30 /* Lowlevel coreswitching */
31 int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
32 {
33         int err;
34         int attempts = 0;
35         u32 cur_core;
36
37         while (1) {
38                 err = pci_write_config_dword(bus->host_pci, SSB_BAR0_WIN,
39                                              (coreidx * SSB_CORE_SIZE)
40                                              + SSB_ENUM_BASE);
41                 if (err)
42                         goto error;
43                 err = pci_read_config_dword(bus->host_pci, SSB_BAR0_WIN,
44                                             &cur_core);
45                 if (err)
46                         goto error;
47                 cur_core = (cur_core - SSB_ENUM_BASE)
48                            / SSB_CORE_SIZE;
49                 if (cur_core == coreidx)
50                         break;
51
52                 if (attempts++ > SSB_BAR0_MAX_RETRIES)
53                         goto error;
54                 udelay(10);
55         }
56         return 0;
57 error:
58         ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
59         return -ENODEV;
60 }
61
62 int ssb_pci_switch_core(struct ssb_bus *bus,
63                         struct ssb_device *dev)
64 {
65         int err;
66         unsigned long flags;
67
68 #if SSB_VERBOSE_PCICORESWITCH_DEBUG
69         ssb_printk(KERN_INFO PFX
70                    "Switching to %s core, index %d\n",
71                    ssb_core_name(dev->id.coreid),
72                    dev->core_index);
73 #endif
74
75         spin_lock_irqsave(&bus->bar_lock, flags);
76         err = ssb_pci_switch_coreidx(bus, dev->core_index);
77         if (!err)
78                 bus->mapped_device = dev;
79         spin_unlock_irqrestore(&bus->bar_lock, flags);
80
81         return err;
82 }
83
84 /* Enable/disable the on board crystal oscillator and/or PLL. */
85 int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
86 {
87         int err;
88         u32 in, out, outenable;
89         u16 pci_status;
90
91         if (bus->bustype != SSB_BUSTYPE_PCI)
92                 return 0;
93
94         err = pci_read_config_dword(bus->host_pci, SSB_GPIO_IN, &in);
95         if (err)
96                 goto err_pci;
97         err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &out);
98         if (err)
99                 goto err_pci;
100         err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, &outenable);
101         if (err)
102                 goto err_pci;
103
104         outenable |= what;
105
106         if (turn_on) {
107                 /* Avoid glitching the clock if GPRS is already using it.
108                  * We can't actually read the state of the PLLPD so we infer it
109                  * by the value of XTAL_PU which *is* readable via gpioin.
110                  */
111                 if (!(in & SSB_GPIO_XTAL)) {
112                         if (what & SSB_GPIO_XTAL) {
113                                 /* Turn the crystal on */
114                                 out |= SSB_GPIO_XTAL;
115                                 if (what & SSB_GPIO_PLL)
116                                         out |= SSB_GPIO_PLL;
117                                 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
118                                 if (err)
119                                         goto err_pci;
120                                 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE,
121                                                              outenable);
122                                 if (err)
123                                         goto err_pci;
124                                 msleep(1);
125                         }
126                         if (what & SSB_GPIO_PLL) {
127                                 /* Turn the PLL on */
128                                 out &= ~SSB_GPIO_PLL;
129                                 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
130                                 if (err)
131                                         goto err_pci;
132                                 msleep(5);
133                         }
134                 }
135
136                 err = pci_read_config_word(bus->host_pci, PCI_STATUS, &pci_status);
137                 if (err)
138                         goto err_pci;
139                 pci_status &= ~PCI_STATUS_SIG_TARGET_ABORT;
140                 err = pci_write_config_word(bus->host_pci, PCI_STATUS, pci_status);
141                 if (err)
142                         goto err_pci;
143         } else {
144                 if (what & SSB_GPIO_XTAL) {
145                         /* Turn the crystal off */
146                         out &= ~SSB_GPIO_XTAL;
147                 }
148                 if (what & SSB_GPIO_PLL) {
149                         /* Turn the PLL off */
150                         out |= SSB_GPIO_PLL;
151                 }
152                 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
153                 if (err)
154                         goto err_pci;
155                 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, outenable);
156                 if (err)
157                         goto err_pci;
158         }
159
160 out:
161         return err;
162
163 err_pci:
164         printk(KERN_ERR PFX "Error: ssb_pci_xtal() could not access PCI config space!\n");
165         err = -EBUSY;
166         goto out;
167 }
168
169 /* Get the word-offset for a SSB_SPROM_XXX define. */
170 #define SPOFF(offset)   (((offset) - SSB_SPROM_BASE) / sizeof(u16))
171 /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
172 #define SPEX(_outvar, _offset, _mask, _shift)   \
173         out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
174
175 static inline u8 ssb_crc8(u8 crc, u8 data)
176 {
177         /* Polynomial:   x^8 + x^7 + x^6 + x^4 + x^2 + 1   */
178         static const u8 t[] = {
179                 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
180                 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
181                 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
182                 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
183                 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
184                 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
185                 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
186                 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
187                 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
188                 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
189                 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
190                 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
191                 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
192                 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
193                 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
194                 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
195                 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
196                 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
197                 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
198                 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
199                 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
200                 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
201                 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
202                 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
203                 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
204                 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
205                 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
206                 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
207                 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
208                 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
209                 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
210                 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
211         };
212         return t[crc ^ data];
213 }
214
215 static u8 ssb_sprom_crc(const u16 *sprom)
216 {
217         int word;
218         u8 crc = 0xFF;
219
220         for (word = 0; word < SSB_SPROMSIZE_WORDS - 1; word++) {
221                 crc = ssb_crc8(crc, sprom[word] & 0x00FF);
222                 crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
223         }
224         crc = ssb_crc8(crc, sprom[SPOFF(SSB_SPROM_REVISION)] & 0x00FF);
225         crc ^= 0xFF;
226
227         return crc;
228 }
229
230 static int sprom_check_crc(const u16 *sprom)
231 {
232         u8 crc;
233         u8 expected_crc;
234         u16 tmp;
235
236         crc = ssb_sprom_crc(sprom);
237         tmp = sprom[SPOFF(SSB_SPROM_REVISION)] & SSB_SPROM_REVISION_CRC;
238         expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
239         if (crc != expected_crc)
240                 return -EPROTO;
241
242         return 0;
243 }
244
245 static void sprom_do_read(struct ssb_bus *bus, u16 *sprom)
246 {
247         int i;
248
249         for (i = 0; i < SSB_SPROMSIZE_WORDS; i++)
250                 sprom[i] = readw(bus->mmio + SSB_SPROM_BASE + (i * 2));
251 }
252
253 static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
254 {
255         struct pci_dev *pdev = bus->host_pci;
256         int i, err;
257         u32 spromctl;
258
259         ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
260         err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
261         if (err)
262                 goto err_ctlreg;
263         spromctl |= SSB_SPROMCTL_WE;
264         err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
265         if (err)
266                 goto err_ctlreg;
267         ssb_printk(KERN_NOTICE PFX "[ 0%%");
268         msleep(500);
269         for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) {
270                 if (i == SSB_SPROMSIZE_WORDS / 4)
271                         ssb_printk("25%%");
272                 else if (i == SSB_SPROMSIZE_WORDS / 2)
273                         ssb_printk("50%%");
274                 else if (i == (SSB_SPROMSIZE_WORDS / 4) * 3)
275                         ssb_printk("75%%");
276                 else if (i % 2)
277                         ssb_printk(".");
278                 writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2));
279                 mmiowb();
280                 msleep(20);
281         }
282         err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
283         if (err)
284                 goto err_ctlreg;
285         spromctl &= ~SSB_SPROMCTL_WE;
286         err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
287         if (err)
288                 goto err_ctlreg;
289         msleep(500);
290         ssb_printk("100%% ]\n");
291         ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
292
293         return 0;
294 err_ctlreg:
295         ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n");
296         return err;
297 }
298
299 static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in)
300 {
301         int i;
302         u16 v;
303
304         SPEX(pci_spid, SSB_SPROM1_SPID, 0xFFFF, 0);
305         SPEX(pci_svid, SSB_SPROM1_SVID, 0xFFFF, 0);
306         SPEX(pci_pid, SSB_SPROM1_PID, 0xFFFF, 0);
307         for (i = 0; i < 3; i++) {
308                 v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
309                 *(((u16 *)out->il0mac) + i) = cpu_to_be16(v);
310         }
311         for (i = 0; i < 3; i++) {
312                 v = in[SPOFF(SSB_SPROM1_ET0MAC) + i];
313                 *(((u16 *)out->et0mac) + i) = cpu_to_be16(v);
314         }
315         for (i = 0; i < 3; i++) {
316                 v = in[SPOFF(SSB_SPROM1_ET1MAC) + i];
317                 *(((u16 *)out->et1mac) + i) = cpu_to_be16(v);
318         }
319         SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
320         SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
321              SSB_SPROM1_ETHPHY_ET1A_SHIFT);
322         SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
323         SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
324         SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
325         SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
326              SSB_SPROM1_BINF_CCODE_SHIFT);
327         SPEX(antenna_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
328              SSB_SPROM1_BINF_ANTA_SHIFT);
329         SPEX(antenna_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
330              SSB_SPROM1_BINF_ANTBG_SHIFT);
331         SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
332         SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
333         SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
334         SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
335         SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
336         SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
337         SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0);
338         SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1,
339              SSB_SPROM1_GPIOA_P1_SHIFT);
340         SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
341         SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
342              SSB_SPROM1_GPIOB_P3_SHIFT);
343         SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A,
344              SSB_SPROM1_MAXPWR_A_SHIFT);
345         SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0);
346         SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A,
347              SSB_SPROM1_ITSSI_A_SHIFT);
348         SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
349         SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
350         SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0);
351         SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG,
352              SSB_SPROM1_AGAIN_BG_SHIFT);
353         for (i = 0; i < 4; i++) {
354                 v = in[SPOFF(SSB_SPROM1_OEM) + i];
355                 *(((u16 *)out->oem) + i) = cpu_to_le16(v);
356         }
357 }
358
359 static void sprom_extract_r2(struct ssb_sprom_r2 *out, const u16 *in)
360 {
361         int i;
362         u16 v;
363
364         SPEX(boardflags_hi, SSB_SPROM2_BFLHI,  0xFFFF, 0);
365         SPEX(maxpwr_a_hi, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0);
366         SPEX(maxpwr_a_lo, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO,
367              SSB_SPROM2_MAXP_A_LO_SHIFT);
368         SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0);
369         SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0);
370         SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0);
371         SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0);
372         SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0);
373         SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0);
374         SPEX(ofdm_pwr_off, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0);
375         for (i = 0; i < 4; i++) {
376                 v = in[SPOFF(SSB_SPROM2_CCODE) + i];
377                 *(((u16 *)out->country_str) + i) = cpu_to_le16(v);
378         }
379 }
380
381 static void sprom_extract_r3(struct ssb_sprom_r3 *out, const u16 *in)
382 {
383         out->ofdmapo  = (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0xFF00) >> 8;
384         out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0x00FF) << 8;
385         out->ofdmapo <<= 16;
386         out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0xFF00) >> 8;
387         out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0x00FF) << 8;
388
389         out->ofdmalpo  = (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0xFF00) >> 8;
390         out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0x00FF) << 8;
391         out->ofdmalpo <<= 16;
392         out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0xFF00) >> 8;
393         out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0x00FF) << 8;
394
395         out->ofdmahpo  = (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0xFF00) >> 8;
396         out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0x00FF) << 8;
397         out->ofdmahpo <<= 16;
398         out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0xFF00) >> 8;
399         out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0x00FF) << 8;
400
401         SPEX(gpioldc_on_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_ON,
402              SSB_SPROM3_GPIOLDC_ON_SHIFT);
403         SPEX(gpioldc_off_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_OFF,
404              SSB_SPROM3_GPIOLDC_OFF_SHIFT);
405         SPEX(cckpo_1M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_1M, 0);
406         SPEX(cckpo_2M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_2M,
407              SSB_SPROM3_CCKPO_2M_SHIFT);
408         SPEX(cckpo_55M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_55M,
409              SSB_SPROM3_CCKPO_55M_SHIFT);
410         SPEX(cckpo_11M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_11M,
411              SSB_SPROM3_CCKPO_11M_SHIFT);
412
413         out->ofdmgpo  = (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0xFF00) >> 8;
414         out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0x00FF) << 8;
415         out->ofdmgpo <<= 16;
416         out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0xFF00) >> 8;
417         out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0x00FF) << 8;
418 }
419
420 static int sprom_extract(struct ssb_bus *bus,
421                          struct ssb_sprom *out, const u16 *in)
422 {
423         memset(out, 0, sizeof(*out));
424
425         SPEX(revision, SSB_SPROM_REVISION, SSB_SPROM_REVISION_REV, 0);
426         SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC,
427              SSB_SPROM_REVISION_CRC_SHIFT);
428
429         if ((bus->chip_id & 0xFF00) == 0x4400) {
430                 /* Workaround: The BCM44XX chip has a stupid revision
431                  * number stored in the SPROM.
432                  * Always extract r1. */
433                 sprom_extract_r1(&out->r1, in);
434         } else {
435                 if (out->revision == 0)
436                         goto unsupported;
437                 if (out->revision >= 1 && out->revision <= 3)
438                         sprom_extract_r1(&out->r1, in);
439                 if (out->revision >= 2 && out->revision <= 3)
440                         sprom_extract_r2(&out->r2, in);
441                 if (out->revision == 3)
442                         sprom_extract_r3(&out->r3, in);
443                 if (out->revision >= 4)
444                         goto unsupported;
445         }
446
447         return 0;
448 unsupported:
449         ssb_printk(KERN_WARNING PFX "Unsupported SPROM revision %d "
450                    "detected. Will extract v1\n", out->revision);
451         sprom_extract_r1(&out->r1, in);
452         return 0;
453 }
454
455 static int ssb_pci_sprom_get(struct ssb_bus *bus,
456                              struct ssb_sprom *sprom)
457 {
458         int err = -ENOMEM;
459         u16 *buf;
460
461         buf = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
462         if (!buf)
463                 goto out;
464         sprom_do_read(bus, buf);
465         err = sprom_check_crc(buf);
466         if (err) {
467                 ssb_printk(KERN_WARNING PFX
468                            "WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
469         }
470         err = sprom_extract(bus, sprom, buf);
471
472         kfree(buf);
473 out:
474         return err;
475 }
476
477 static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
478                                   struct ssb_boardinfo *bi)
479 {
480         pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
481                              &bi->vendor);
482         pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
483                              &bi->type);
484         pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
485                              &bi->rev);
486 }
487
488 int ssb_pci_get_invariants(struct ssb_bus *bus,
489                            struct ssb_init_invariants *iv)
490 {
491         int err;
492
493         err = ssb_pci_sprom_get(bus, &iv->sprom);
494         if (err)
495                 goto out;
496         ssb_pci_get_boardinfo(bus, &iv->boardinfo);
497
498 out:
499         return err;
500 }
501
502 #ifdef CONFIG_SSB_DEBUG
503 static int ssb_pci_assert_buspower(struct ssb_bus *bus)
504 {
505         if (likely(bus->powered_up))
506                 return 0;
507
508         printk(KERN_ERR PFX "FATAL ERROR: Bus powered down "
509                "while accessing PCI MMIO space\n");
510         if (bus->power_warn_count <= 10) {
511                 bus->power_warn_count++;
512                 dump_stack();
513         }
514
515         return -ENODEV;
516 }
517 #else /* DEBUG */
518 static inline int ssb_pci_assert_buspower(struct ssb_bus *bus)
519 {
520         return 0;
521 }
522 #endif /* DEBUG */
523
524 static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
525 {
526         struct ssb_bus *bus = dev->bus;
527
528         if (unlikely(ssb_pci_assert_buspower(bus)))
529                 return 0xFFFF;
530         if (unlikely(bus->mapped_device != dev)) {
531                 if (unlikely(ssb_pci_switch_core(bus, dev)))
532                         return 0xFFFF;
533         }
534         return readw(bus->mmio + offset);
535 }
536
537 static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset)
538 {
539         struct ssb_bus *bus = dev->bus;
540
541         if (unlikely(ssb_pci_assert_buspower(bus)))
542                 return 0xFFFFFFFF;
543         if (unlikely(bus->mapped_device != dev)) {
544                 if (unlikely(ssb_pci_switch_core(bus, dev)))
545                         return 0xFFFFFFFF;
546         }
547         return readl(bus->mmio + offset);
548 }
549
550 static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value)
551 {
552         struct ssb_bus *bus = dev->bus;
553
554         if (unlikely(ssb_pci_assert_buspower(bus)))
555                 return;
556         if (unlikely(bus->mapped_device != dev)) {
557                 if (unlikely(ssb_pci_switch_core(bus, dev)))
558                         return;
559         }
560         writew(value, bus->mmio + offset);
561 }
562
563 static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value)
564 {
565         struct ssb_bus *bus = dev->bus;
566
567         if (unlikely(ssb_pci_assert_buspower(bus)))
568                 return;
569         if (unlikely(bus->mapped_device != dev)) {
570                 if (unlikely(ssb_pci_switch_core(bus, dev)))
571                         return;
572         }
573         writel(value, bus->mmio + offset);
574 }
575
576 /* Not "static", as it's used in main.c */
577 const struct ssb_bus_ops ssb_pci_ops = {
578         .read16         = ssb_pci_read16,
579         .read32         = ssb_pci_read32,
580         .write16        = ssb_pci_write16,
581         .write32        = ssb_pci_write32,
582 };
583
584 static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len)
585 {
586         int i, pos = 0;
587
588         for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) {
589                 pos += snprintf(buf + pos, buf_len - pos - 1,
590                                 "%04X", swab16(sprom[i]) & 0xFFFF);
591         }
592         pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
593
594         return pos + 1;
595 }
596
597 static int hex2sprom(u16 *sprom, const char *dump, size_t len)
598 {
599         char tmp[5] = { 0 };
600         int cnt = 0;
601         unsigned long parsed;
602
603         if (len < SSB_SPROMSIZE_BYTES * 2)
604                 return -EINVAL;
605
606         while (cnt < SSB_SPROMSIZE_WORDS) {
607                 memcpy(tmp, dump, 4);
608                 dump += 4;
609                 parsed = simple_strtoul(tmp, NULL, 16);
610                 sprom[cnt++] = swab16((u16)parsed);
611         }
612
613         return 0;
614 }
615
616 static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
617                                        struct device_attribute *attr,
618                                        char *buf)
619 {
620         struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
621         struct ssb_bus *bus;
622         u16 *sprom;
623         int err = -ENODEV;
624         ssize_t count = 0;
625
626         bus = ssb_pci_dev_to_bus(pdev);
627         if (!bus)
628                 goto out;
629         err = -ENOMEM;
630         sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
631         if (!sprom)
632                 goto out;
633
634         /* Use interruptible locking, as the SPROM write might
635          * be holding the lock for several seconds. So allow userspace
636          * to cancel operation. */
637         err = -ERESTARTSYS;
638         if (mutex_lock_interruptible(&bus->pci_sprom_mutex))
639                 goto out_kfree;
640         sprom_do_read(bus, sprom);
641         mutex_unlock(&bus->pci_sprom_mutex);
642
643         count = sprom2hex(sprom, buf, PAGE_SIZE);
644         err = 0;
645
646 out_kfree:
647         kfree(sprom);
648 out:
649         return err ? err : count;
650 }
651
652 static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
653                                         struct device_attribute *attr,
654                                         const char *buf, size_t count)
655 {
656         struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
657         struct ssb_bus *bus;
658         u16 *sprom;
659         int res = 0, err = -ENODEV;
660
661         bus = ssb_pci_dev_to_bus(pdev);
662         if (!bus)
663                 goto out;
664         err = -ENOMEM;
665         sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
666         if (!sprom)
667                 goto out;
668         err = hex2sprom(sprom, buf, count);
669         if (err) {
670                 err = -EINVAL;
671                 goto out_kfree;
672         }
673         err = sprom_check_crc(sprom);
674         if (err) {
675                 err = -EINVAL;
676                 goto out_kfree;
677         }
678
679         /* Use interruptible locking, as the SPROM write might
680          * be holding the lock for several seconds. So allow userspace
681          * to cancel operation. */
682         err = -ERESTARTSYS;
683         if (mutex_lock_interruptible(&bus->pci_sprom_mutex))
684                 goto out_kfree;
685         err = ssb_devices_freeze(bus);
686         if (err == -EOPNOTSUPP) {
687                 ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze devices. "
688                            "No suspend support. Is CONFIG_PM enabled?\n");
689                 goto out_unlock;
690         }
691         if (err) {
692                 ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n");
693                 goto out_unlock;
694         }
695         res = sprom_do_write(bus, sprom);
696         err = ssb_devices_thaw(bus);
697         if (err)
698                 ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n");
699 out_unlock:
700         mutex_unlock(&bus->pci_sprom_mutex);
701 out_kfree:
702         kfree(sprom);
703 out:
704         if (res)
705                 return res;
706         return err ? err : count;
707 }
708
709 static DEVICE_ATTR(ssb_sprom, 0600,
710                    ssb_pci_attr_sprom_show,
711                    ssb_pci_attr_sprom_store);
712
713 void ssb_pci_exit(struct ssb_bus *bus)
714 {
715         struct pci_dev *pdev;
716
717         if (bus->bustype != SSB_BUSTYPE_PCI)
718                 return;
719
720         pdev = bus->host_pci;
721         device_remove_file(&pdev->dev, &dev_attr_ssb_sprom);
722 }
723
724 int ssb_pci_init(struct ssb_bus *bus)
725 {
726         struct pci_dev *pdev;
727         int err;
728
729         if (bus->bustype != SSB_BUSTYPE_PCI)
730                 return 0;
731
732         pdev = bus->host_pci;
733         mutex_init(&bus->pci_sprom_mutex);
734         err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);
735         if (err)
736                 goto out;
737
738 out:
739         return err;
740 }