Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 May 2017 06:20:06 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r318696 - head/sys/mips/atheros
Message-ID:  <201705230620.v4N6K6hT049845@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Tue May 23 06:20:06 2017
New Revision: 318696
URL: https://svnweb.freebsd.org/changeset/base/318696

Log:
  [ar71xx] add a very simple early boot driver called "caldata" to commit cross-layer atrocities.
  
  The (eventually) upcoming ath(4) changes will include being able to load
  ath(4) devices on the AHB bus (ie the on-die wifi part of the SoC)
  as modules.
  
  In order for this to happen, a copy of the calibration data needs to be
  copied away before the SPI driver runs or the memory map access hack
  won't work.
  
  Now, ideally (!) there'd be some driver that can come up after the MTD
  pieces (eg, SPI, NAND, etc) and load into a firmware chunk the calibration
  data.
  
  (Or, really really nicely, would be an actual async firmware API that
  would lead itself to having a driver schedule a file read - or a raw device
  read - to get to the calibration data.)
  
  Now, until all of the above is done - I'm going to perpetuate the layer
  breaking atrocity here by simply doing the PCI bus fixup EEPROM/calibration
  data hack here.  This will work for any AR71xx (and later on, AR231x/AR531x)
  device, as well as the handful of QCA MIPS + QCA9880v2 802.11ac boards with
  NOR flash.
  
  To use, this goes into the kernel config:
  
  # Enable EEPROM hacks
  options AR71XX_ATH_EEPROM
  device ar71xx_caldata
  device firmware
  
  # This enables the ath_ahb driver (when I commit the change!) to
  # pull data out of the firmware hack.
  options ATH_EEPROM_FIRMWARE
  
  In the hints file:
  
  # ART calibration data mapping device
  hint.ar71xx_caldata.0.at="nexus0"
  hint.ar71xx_caldata.0.order=0
  
  # Where the ART is - last 64k in the first 8MB of flash
  hint.ar71xx_caldata.0.map.0.ath_fixup_addr=0x1fff0000
  hint.ar71xx_caldata.0.map.0.ath_fixup_size=16384
  
  # And now tell the ath(4) driver where to look!
  hint.ath.0.eeprom_firmware="ar71xx_caldata.0.map.0.eeprom_firmware"
  
  Tested:
  
  * carambola2, AR933x SoC, using a set of ath and ath_hal modules to load
  
  TODO:
  
  * unify this bit of firmware loading code, as I will definitely need
    to include both the PCI bus firmware version (for PCI ID fixups too!)
    as well as AHB/on-chip calibration data.
  
  * Commit the ath_ahb bus code
  
  * Convert .. everything over.  That'll take the majority of the time.

Added:
  head/sys/mips/atheros/ar71xx_caldata.c   (contents, props changed)
Modified:
  head/sys/mips/atheros/files.ar71xx

Added: head/sys/mips/atheros/ar71xx_caldata.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/atheros/ar71xx_caldata.c	Tue May 23 06:20:06 2017	(r318696)
@@ -0,0 +1,176 @@
+/*-
+ * Copyright (c) 2017, Adrian Chadd <adrian@FreeBSD.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ar71xx.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr_machdep.h>
+
+#include <sys/linker.h>
+#include <sys/firmware.h>
+
+struct ar71xx_caldata_softc {
+	device_t		sc_dev;
+};
+
+static int
+ar71xx_caldata_probe(device_t dev)
+{
+
+	return (BUS_PROBE_NOWILDCARD);
+}
+
+/* XXX TODO: unify with what's in ar71xx_fixup.c */
+
+/*
+ * Create a calibration block from memory mapped SPI data for use by
+ * various drivers.  Right now it's just ath(4) but later board support
+ * will include 802.11ac NICs with calibration data in NOR flash.
+ *
+ * (Yes, there are a handful of QCA MIPS boards with QCA9880v2 802.11ac chips
+ * with calibration data in flash..)
+ */
+static void
+ar71xx_platform_create_cal_data(device_t dev, int id, long int flash_addr,
+    int size)
+{
+	char buf[64];
+	uint16_t *cal_data = (uint16_t *) MIPS_PHYS_TO_KSEG1(flash_addr);
+	void *eeprom = NULL;
+	const struct firmware *fw = NULL;
+
+	device_printf(dev, "EEPROM firmware: 0x%lx @ %d bytes\n",
+	    flash_addr, size);
+
+	eeprom = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO);
+	if (! eeprom) {
+		device_printf(dev, "%s: malloc failed for '%s', aborting EEPROM\n",
+		__func__, buf);
+		return;
+	}
+
+	memcpy(eeprom, cal_data, size);
+
+	/*
+	 * Generate a flash EEPROM 'firmware' from the given memory
+	 * region.  Since the SPI controller will eventually
+	 * go into port-IO mode instead of memory-mapped IO
+	 * mode, a copy of the EEPROM contents is required.
+	 */
+
+	snprintf(buf, sizeof(buf), "%s.%d.map.%d.eeprom_firmware",
+	    device_get_name(dev),
+	    device_get_unit(dev),
+	    id);
+
+	fw = firmware_register(buf, eeprom, size, 1, NULL);
+	if (fw == NULL) {
+		device_printf(dev, "%s: firmware_register (%s) failed\n",
+		    __func__, buf);
+		free(eeprom, M_DEVBUF);
+		return;
+	}
+	device_printf(dev, "device EEPROM '%s' registered\n", buf);
+}
+
+/*
+ * Iterate through a list of early-boot hints creating calibration
+ * data firmware chunks for AHB (ie, non-PCI) devices with calibration
+ * data.
+ */
+static int
+ar71xx_platform_check_eeprom_hints(device_t dev)
+{
+	char buf[64];
+	long int addr;
+	int size;
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		snprintf(buf, sizeof(buf), "map.%d.ath_fixup_addr", i);
+		if (resource_long_value(device_get_name(dev),
+		    device_get_unit(dev), buf, &addr) != 0)
+			break;
+		snprintf(buf, sizeof(buf), "map.%d.ath_fixup_size", i);
+		if (resource_int_value(device_get_name(dev),
+		    device_get_unit(dev), buf, &size) != 0)
+			break;
+		device_printf(dev, "map.%d.ath_fixup_addr=0x%08x; size=%d\n",
+		    i, (int) addr, size);
+		(void) ar71xx_platform_create_cal_data(dev, i, addr, size);
+        }
+
+        return (0);
+}
+
+static int
+ar71xx_caldata_attach(device_t dev)
+{
+
+	device_add_child(dev, "nexus", -1);
+	ar71xx_platform_check_eeprom_hints(dev);
+	return (bus_generic_attach(dev));
+}
+
+static device_method_t ar71xx_caldata_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ar71xx_caldata_probe),
+	DEVMETHOD(device_attach,	ar71xx_caldata_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+	DEVMETHOD_END
+};
+
+static driver_t ar71xx_caldata_driver = {
+	"ar71xx_caldata",
+	ar71xx_caldata_methods,
+	sizeof(struct ar71xx_caldata_softc),
+};
+
+static devclass_t ar71xx_caldata_devclass;
+
+DRIVER_MODULE(ar71xx_caldata, nexus, ar71xx_caldata_driver, ar71xx_caldata_devclass, 0, 0);

Modified: head/sys/mips/atheros/files.ar71xx
==============================================================================
--- head/sys/mips/atheros/files.ar71xx	Tue May 23 06:14:02 2017	(r318695)
+++ head/sys/mips/atheros/files.ar71xx	Tue May 23 06:20:06 2017	(r318696)
@@ -1,6 +1,7 @@
 # $FreeBSD$
 
 mips/atheros/apb.c		optional ar71xx_apb
+mips/atheros/ar71xx_caldata.c	optional ar71xx_caldata
 mips/atheros/ar71xx_gpio.c	optional gpio
 mips/atheros/ar71xx_machdep.c	standard
 mips/atheros/ar71xx_ehci.c	optional ehci



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201705230620.v4N6K6hT049845>