xref: /freebsd/sys/dev/bhnd/cores/chipc/chipc.c (revision 8ef24a0d4b28fe230e20637f56869cc4148cd2ca)
1 /*-
2  * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 /*
34  * Broadcom ChipCommon driver.
35  *
36  * With the exception of some very early chipsets, the ChipCommon core
37  * has been included in all HND SoCs and chipsets based on the siba(4)
38  * and bcma(4) interconnects, providing a common interface to chipset
39  * identification, bus enumeration, UARTs, clocks, watchdog interrupts, GPIO,
40  * flash, etc.
41  */
42 
43 #include <sys/param.h>
44 #include <sys/kernel.h>
45 #include <sys/bus.h>
46 #include <sys/module.h>
47 #include <sys/systm.h>
48 
49 #include <machine/bus.h>
50 #include <sys/rman.h>
51 #include <machine/resource.h>
52 
53 #include <dev/bhnd/bhnd.h>
54 
55 #include "bhnd_nvram_if.h"
56 
57 #include "chipcreg.h"
58 #include "chipcvar.h"
59 
60 devclass_t bhnd_chipc_devclass;	/**< bhnd(4) chipcommon device class */
61 
62 static const struct resource_spec chipc_rspec[CHIPC_MAX_RSPEC] = {
63 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
64 	{ -1, -1, 0 }
65 };
66 
67 static struct bhnd_device_quirk chipc_quirks[];
68 static struct bhnd_chip_quirk chipc_chip_quirks[];
69 
70 /* Supported device identifiers */
71 static const struct bhnd_device chipc_devices[] = {
72 	BHND_DEVICE(CC, "CC", chipc_quirks, chipc_chip_quirks),
73 	BHND_DEVICE_END
74 };
75 
76 
77 /* Device quirks table */
78 static struct bhnd_device_quirk chipc_quirks[] = {
79 	{ BHND_HWREV_GTE	(32),	CHIPC_QUIRK_SUPPORTS_SPROM },
80 	{ BHND_HWREV_GTE	(35),	CHIPC_QUIRK_SUPPORTS_NFLASH },
81 	BHND_DEVICE_QUIRK_END
82 };
83 
84 /* Chip-specific quirks table */
85 static struct bhnd_chip_quirk chipc_chip_quirks[] = {
86 	/* 4331 12x9 packages */
87 	{{ BHND_CHIP_IP(4331, 4331TN) },
88 		CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM
89 	},
90 	{{ BHND_CHIP_IP(4331, 4331TNA0) },
91 		CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM
92 	},
93 
94 	/* 4331 12x12 packages */
95 	{{ BHND_CHIP_IPR(4331, 4331TT, HWREV_GTE(1)) },
96 		CHIPC_QUIRK_4331_EXTPA2_MUX_SPROM
97 	},
98 
99 	/* 4331 (all packages/revisions) */
100 	{{ BHND_CHIP_ID(4331) },
101 		CHIPC_QUIRK_4331_EXTPA_MUX_SPROM
102 	},
103 
104 	/* 4360 family (all revs <= 2) */
105 	{{ BHND_CHIP_IR(4352, HWREV_LTE(2)) },
106 		CHIPC_QUIRK_4360_FEM_MUX_SPROM },
107 	{{ BHND_CHIP_IR(43460, HWREV_LTE(2)) },
108 		CHIPC_QUIRK_4360_FEM_MUX_SPROM },
109 	{{ BHND_CHIP_IR(43462, HWREV_LTE(2)) },
110 		CHIPC_QUIRK_4360_FEM_MUX_SPROM },
111 	{{ BHND_CHIP_IR(43602, HWREV_LTE(2)) },
112 		CHIPC_QUIRK_4360_FEM_MUX_SPROM },
113 
114 	BHND_CHIP_QUIRK_END
115 };
116 
117 /* quirk and capability flag convenience macros */
118 #define	CHIPC_QUIRK(_sc, _name)	\
119     ((_sc)->quirks & CHIPC_QUIRK_ ## _name)
120 
121 #define CHIPC_CAP(_sc, _name)	\
122     ((_sc)->caps & CHIPC_ ## _name)
123 
124 #define	CHIPC_ASSERT_QUIRK(_sc, name)	\
125     KASSERT(CHIPC_QUIRK((_sc), name), ("quirk " __STRING(_name) " not set"))
126 
127 #define	CHIPC_ASSERT_CAP(_sc, name)	\
128     KASSERT(CHIPC_CAP((_sc), name), ("capability " __STRING(_name) " not set"))
129 
130 static bhnd_nvram_src_t	chipc_nvram_identify(struct chipc_softc *sc);
131 static int		chipc_sprom_init(struct chipc_softc *);
132 static int		chipc_enable_sprom_pins(struct chipc_softc *);
133 static int		chipc_disable_sprom_pins(struct chipc_softc *);
134 
135 
136 static int
137 chipc_probe(device_t dev)
138 {
139 	const struct bhnd_device *id;
140 
141 	id = bhnd_device_lookup(dev, chipc_devices, sizeof(chipc_devices[0]));
142 	if (id == NULL)
143 		return (ENXIO);
144 
145 	bhnd_set_default_core_desc(dev);
146 	return (BUS_PROBE_DEFAULT);
147 }
148 
149 static int
150 chipc_attach(device_t dev)
151 {
152 	struct chipc_softc		*sc;
153 	bhnd_addr_t			 enum_addr;
154 	uint32_t			 ccid_reg;
155 	uint8_t				 chip_type;
156 	int				 error;
157 
158 	sc = device_get_softc(dev);
159 	sc->dev = dev;
160 	sc->quirks = bhnd_device_quirks(dev, chipc_devices,
161 	    sizeof(chipc_devices[0]));
162 
163 	CHIPC_LOCK_INIT(sc);
164 
165 	/* Allocate bus resources */
166 	memcpy(sc->rspec, chipc_rspec, sizeof(sc->rspec));
167 	if ((error = bhnd_alloc_resources(dev, sc->rspec, sc->res)))
168 		return (error);
169 
170 	sc->core = sc->res[0];
171 
172 	/* Fetch our chipset identification data */
173 	ccid_reg = bhnd_bus_read_4(sc->core, CHIPC_ID);
174 	chip_type = CHIPC_GET_ATTR(ccid_reg, ID_BUS);
175 
176 	switch (chip_type) {
177 	case BHND_CHIPTYPE_SIBA:
178 		/* enumeration space starts at the ChipCommon register base. */
179 		enum_addr = rman_get_start(sc->core->res);
180 		break;
181 	case BHND_CHIPTYPE_BCMA:
182 	case BHND_CHIPTYPE_BCMA_ALT:
183 		enum_addr = bhnd_bus_read_4(sc->core, CHIPC_EROMPTR);
184 		break;
185 	default:
186 		device_printf(dev, "unsupported chip type %hhu\n", chip_type);
187 		error = ENODEV;
188 		goto cleanup;
189 	}
190 
191 	sc->ccid = bhnd_parse_chipid(ccid_reg, enum_addr);
192 
193 	/* Fetch capability and status register values */
194 	sc->caps = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES);
195 	sc->cst = bhnd_bus_read_4(sc->core, CHIPC_CHIPST);
196 
197 	/* Identify NVRAM source */
198 	sc->nvram_src = chipc_nvram_identify(sc);
199 
200 	/* Read NVRAM data */
201 	switch (sc->nvram_src) {
202 	case BHND_NVRAM_SRC_OTP:
203 		// TODO (requires access to OTP hardware)
204 		device_printf(sc->dev, "NVRAM-OTP unsupported\n");
205 		break;
206 
207 	case BHND_NVRAM_SRC_NFLASH:
208 		// TODO (requires access to NFLASH hardware)
209 		device_printf(sc->dev, "NVRAM-NFLASH unsupported\n");
210 		break;
211 
212 	case BHND_NVRAM_SRC_SPROM:
213 		if ((error = chipc_sprom_init(sc)))
214 			goto cleanup;
215 		break;
216 
217 	case BHND_NVRAM_SRC_UNKNOWN:
218 		/* Handled externally */
219 		break;
220 	}
221 
222 	return (0);
223 
224 cleanup:
225 	bhnd_release_resources(dev, sc->rspec, sc->res);
226 	CHIPC_LOCK_DESTROY(sc);
227 	return (error);
228 }
229 
230 static int
231 chipc_detach(device_t dev)
232 {
233 	struct chipc_softc	*sc;
234 
235 	sc = device_get_softc(dev);
236 	bhnd_release_resources(dev, sc->rspec, sc->res);
237 	bhnd_sprom_fini(&sc->sprom);
238 
239 	CHIPC_LOCK_DESTROY(sc);
240 
241 	return (0);
242 }
243 
244 static int
245 chipc_suspend(device_t dev)
246 {
247 	return (0);
248 }
249 
250 static int
251 chipc_resume(device_t dev)
252 {
253 	return (0);
254 }
255 
256 /**
257  * Initialize local SPROM shadow, if required.
258  *
259  * @param sc chipc driver state.
260  */
261 static int
262 chipc_sprom_init(struct chipc_softc *sc)
263 {
264 	int	error;
265 
266 	KASSERT(sc->nvram_src == BHND_NVRAM_SRC_SPROM,
267 	    ("non-SPROM source (%u)\n", sc->nvram_src));
268 
269 	/* Enable access to the SPROM */
270 	CHIPC_LOCK(sc);
271 	if ((error = chipc_enable_sprom_pins(sc)))
272 		goto failed;
273 
274 	/* Initialize SPROM parser */
275 	error = bhnd_sprom_init(&sc->sprom, sc->core, CHIPC_SPROM_OTP);
276 	if (error) {
277 		device_printf(sc->dev, "SPROM identification failed: %d\n",
278 			error);
279 
280 		chipc_disable_sprom_pins(sc);
281 		goto failed;
282 	}
283 
284 	/* Drop access to the SPROM lines */
285 	if ((error = chipc_disable_sprom_pins(sc))) {
286 		bhnd_sprom_fini(&sc->sprom);
287 		goto failed;
288 	}
289 	CHIPC_UNLOCK(sc);
290 
291 	return (0);
292 
293 failed:
294 	CHIPC_UNLOCK(sc);
295 	return (error);
296 }
297 
298 /**
299  * Determine the NVRAM data source for this device.
300  *
301  * @param sc chipc driver state.
302  */
303 static bhnd_nvram_src_t
304 chipc_nvram_identify(struct chipc_softc *sc)
305 {
306 	uint32_t		 srom_ctrl;
307 
308 	/* Very early devices vend SPROM/OTP/CIS (if at all) via the
309 	 * host bridge interface instead of ChipCommon. */
310 	if (!CHIPC_QUIRK(sc, SUPPORTS_SPROM))
311 		return (BHND_NVRAM_SRC_UNKNOWN);
312 
313 	/*
314 	 * Later chipset revisions standardized the SPROM capability flags and
315 	 * register interfaces.
316 	 *
317 	 * We check for hardware presence in order of precedence. For example,
318 	 * SPROM is is always used in preference to internal OTP if found.
319 	 */
320 	if (CHIPC_CAP(sc, CAP_SPROM)) {
321 		srom_ctrl = bhnd_bus_read_4(sc->core, CHIPC_SPROM_CTRL);
322 		if (srom_ctrl & CHIPC_SRC_PRESENT)
323 			return (BHND_NVRAM_SRC_SPROM);
324 	}
325 
326 	/* Check for OTP */
327 	if (CHIPC_CAP(sc, CAP_OTP_SIZE))
328 		return (BHND_NVRAM_SRC_OTP);
329 
330 	/*
331 	 * Finally, Northstar chipsets (and possibly other chipsets?) support
332 	 * external NAND flash.
333 	 */
334 	if (CHIPC_QUIRK(sc, SUPPORTS_NFLASH) && CHIPC_CAP(sc, CAP_NFLASH))
335 		return (BHND_NVRAM_SRC_NFLASH);
336 
337 	/* No NVRAM hardware capability declared */
338 	return (BHND_NVRAM_SRC_UNKNOWN);
339 }
340 
341 
342 /**
343  * If required by this device, enable access to the SPROM.
344  *
345  * @param sc chipc driver state.
346  */
347 static int
348 chipc_enable_sprom_pins(struct chipc_softc *sc)
349 {
350 	uint32_t cctrl;
351 
352 	CHIPC_LOCK_ASSERT(sc, MA_OWNED);
353 
354 	/* Nothing to do? */
355 	if (!CHIPC_QUIRK(sc, MUX_SPROM))
356 		return (0);
357 
358 	cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
359 
360 	/* 4331 devices */
361 	if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) {
362 		cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN;
363 
364 		if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM))
365 			cctrl &= ~CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5;
366 
367 		if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM))
368 			cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN2;
369 
370 		bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
371 		return (0);
372 	}
373 
374 	/* 4360 devices */
375 	if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) {
376 		/* Unimplemented */
377 	}
378 
379 	/* Refuse to proceed on unsupported devices with muxed SPROM pins */
380 	device_printf(sc->dev, "muxed sprom lines on unrecognized device\n");
381 	return (ENXIO);
382 }
383 
384 /**
385  * If required by this device, revert any GPIO/pin configuration applied
386  * to allow SPROM access.
387  *
388  * @param sc chipc driver state.
389  */
390 static int
391 chipc_disable_sprom_pins(struct chipc_softc *sc)
392 {
393 	uint32_t cctrl;
394 
395 	CHIPC_LOCK_ASSERT(sc, MA_OWNED);
396 
397 	/* Nothing to do? */
398 	if (!CHIPC_QUIRK(sc, MUX_SPROM))
399 		return (0);
400 
401 	cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
402 
403 	/* 4331 devices */
404 	if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) {
405 		cctrl |= CHIPC_CCTRL4331_EXTPA_EN;
406 
407 		if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM))
408 			cctrl |= CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5;
409 
410 		if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM))
411 			cctrl |= CHIPC_CCTRL4331_EXTPA_EN2;
412 
413 		bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
414 		return (0);
415 	}
416 
417 	/* 4360 devices */
418 	if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) {
419 		/* Unimplemented */
420 	}
421 
422 	/* Refuse to proceed on unsupported devices with muxed SPROM pins */
423 	device_printf(sc->dev, "muxed sprom lines on unrecognized device\n");
424 	return (ENXIO);
425 }
426 
427 static bhnd_nvram_src_t
428 chipc_nvram_src(device_t dev)
429 {
430 	struct chipc_softc *sc = device_get_softc(dev);
431 	return (sc->nvram_src);
432 }
433 
434 static int
435 chipc_nvram_getvar(device_t dev, const char *name, void *buf, size_t *len)
436 {
437 	struct chipc_softc	*sc;
438 	int			 error;
439 
440 	sc = device_get_softc(dev);
441 
442 	switch (sc->nvram_src) {
443 	case BHND_NVRAM_SRC_SPROM:
444 		CHIPC_LOCK(sc);
445 		error = bhnd_sprom_getvar(&sc->sprom, name, buf, len);
446 		CHIPC_UNLOCK(sc);
447 		return (error);
448 
449 	case BHND_NVRAM_SRC_OTP:
450 	case BHND_NVRAM_SRC_NFLASH:
451 		/* Currently unsupported */
452 		return (ENXIO);
453 
454 	case BHND_NVRAM_SRC_UNKNOWN:
455 		return (ENODEV);
456 	}
457 
458 	/* Unknown NVRAM source */
459 	return (ENODEV);
460 }
461 
462 static int
463 chipc_nvram_setvar(device_t dev, const char *name, const void *buf,
464     size_t len)
465 {
466 	struct chipc_softc	*sc;
467 	int			 error;
468 
469 	sc = device_get_softc(dev);
470 
471 	switch (sc->nvram_src) {
472 	case BHND_NVRAM_SRC_SPROM:
473 		CHIPC_LOCK(sc);
474 		error = bhnd_sprom_setvar(&sc->sprom, name, buf, len);
475 		CHIPC_UNLOCK(sc);
476 		return (error);
477 
478 	case BHND_NVRAM_SRC_OTP:
479 	case BHND_NVRAM_SRC_NFLASH:
480 		/* Currently unsupported */
481 		return (ENXIO);
482 
483 	case BHND_NVRAM_SRC_UNKNOWN:
484 	default:
485 		return (ENODEV);
486 	}
487 
488 	/* Unknown NVRAM source */
489 	return (ENODEV);
490 }
491 
492 static void
493 chipc_write_chipctrl(device_t dev, uint32_t value, uint32_t mask)
494 {
495 	struct chipc_softc	*sc;
496 	uint32_t		 cctrl;
497 
498 	sc = device_get_softc(dev);
499 
500 	CHIPC_LOCK(sc);
501 
502 	cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
503 	cctrl = (cctrl & ~mask) | (value | mask);
504 	bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
505 
506 	CHIPC_UNLOCK(sc);
507 }
508 
509 static device_method_t chipc_methods[] = {
510 	/* Device interface */
511 	DEVMETHOD(device_probe,			chipc_probe),
512 	DEVMETHOD(device_attach,		chipc_attach),
513 	DEVMETHOD(device_detach,		chipc_detach),
514 	DEVMETHOD(device_suspend,		chipc_suspend),
515 	DEVMETHOD(device_resume,		chipc_resume),
516 
517 	/* ChipCommon interface */
518 	DEVMETHOD(bhnd_chipc_nvram_src,		chipc_nvram_src),
519 	DEVMETHOD(bhnd_chipc_write_chipctrl,	chipc_write_chipctrl),
520 
521 	/* NVRAM interface */
522 	DEVMETHOD(bhnd_nvram_getvar,		chipc_nvram_getvar),
523 	DEVMETHOD(bhnd_nvram_setvar,		chipc_nvram_setvar),
524 
525 	DEVMETHOD_END
526 };
527 
528 DEFINE_CLASS_0(bhnd_chipc, chipc_driver, chipc_methods, sizeof(struct chipc_softc));
529 DRIVER_MODULE(bhnd_chipc, bhnd, chipc_driver, bhnd_chipc_devclass, 0, 0);
530 MODULE_DEPEND(bhnd_chipc, bhnd, 1, 1, 1);
531 MODULE_VERSION(bhnd_chipc, 1);
532