xref: /openbmc/linux/drivers/ssb/pci.c (revision 96de0e252cedffad61b3cb5e05662c591898e69a)
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 		*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
310 	}
311 	for (i = 0; i < 3; i++) {
312 		v = in[SPOFF(SSB_SPROM1_ET0MAC) + i];
313 		*(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
314 	}
315 	for (i = 0; i < 3; i++) {
316 		v = in[SPOFF(SSB_SPROM1_ET1MAC) + i];
317 		*(((__be16 *)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 		*(((__le16 *)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 		*(((__le16 *)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 ioread16(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 ioread32(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 	iowrite16(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 	iowrite32(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 }
741