svn commit: r326301 - in head/sys: dev/bhnd/siba modules/bhnd/siba
Landon J. Fuller
landonf at FreeBSD.org
Tue Nov 28 00:42:46 UTC 2017
Author: landonf
Date: Tue Nov 28 00:42:44 2017
New Revision: 326301
URL: https://svnweb.freebsd.org/changeset/base/326301
Log:
siba(4): Add support for devices have neither PMU nor PWRCTL support.
Very early BHND Wi-Fi devices (e.g. BCM4318) do not support any form of
dynamic clock control; on these devices, any PMU requests that cannot be
met by the device's fixed clock state will return an appropriate error
code.
Approved by: adrian (mentor, implicit)
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/dev/bhnd/siba/siba.c
head/sys/dev/bhnd/siba/sibavar.h
head/sys/modules/bhnd/siba/Makefile
Modified: head/sys/dev/bhnd/siba/siba.c
==============================================================================
--- head/sys/dev/bhnd/siba/siba.c Tue Nov 28 00:41:17 2017 (r326300)
+++ head/sys/dev/bhnd/siba/siba.c Tue Nov 28 00:42:44 2017 (r326301)
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
+#include <dev/bhnd/cores/chipc/chipc.h>
#include <dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.h>
#include "sibareg.h"
@@ -168,8 +169,9 @@ siba_read_ivar(device_t dev, device_t child, int index
return (0);
case SIBA_PMU_PWRCTL:
- panic("bhnd_get_pmu_info() called with "
- "SIBA_PMU_PWRCTL");
+ case SIBA_PMU_FIXED:
+ panic("bhnd_get_pmu_info() called with siba PMU state "
+ "%d", dinfo->pmu_state);
return (ENXIO);
}
@@ -211,8 +213,9 @@ siba_write_ivar(device_t dev, device_t child, int inde
return (0);
case SIBA_PMU_PWRCTL:
- panic("bhnd_set_pmu_info() called with "
- "SIBA_PMU_PWRCTL");
+ case SIBA_PMU_FIXED:
+ panic("bhnd_set_pmu_info() called with siba PMU state "
+ "%d", dinfo->pmu_state);
return (ENXIO);
}
@@ -237,7 +240,10 @@ siba_alloc_pmu(device_t dev, device_t child)
{
struct siba_softc *sc;
struct siba_devinfo *dinfo;
+ device_t chipc;
device_t pwrctl;
+ struct chipc_caps ccaps;
+ siba_pmu_state pmu_state;
int error;
if (device_get_parent(child) != dev)
@@ -245,11 +251,20 @@ siba_alloc_pmu(device_t dev, device_t child)
sc = device_get_softc(dev);
dinfo = device_get_ivars(child);
- pwrctl = bhnd_retain_provider(child, BHND_SERVICE_PWRCTL);
+ pwrctl = NULL;
- /* Unless this is a legacy PWRCTL chipset, defer to bhnd(4)'s PMU
- * implementation */
- if (pwrctl == NULL) {
+ /* Fetch ChipCommon capability flags */
+ chipc = bhnd_retain_provider(child, BHND_SERVICE_CHIPC);
+ if (chipc != NULL) {
+ ccaps = *BHND_CHIPC_GET_CAPS(chipc);
+ bhnd_release_provider(child, chipc, BHND_SERVICE_CHIPC);
+ } else {
+ memset(&ccaps, 0, sizeof(ccaps));
+ }
+
+ /* Defer to bhnd(4)'s PMU implementation if ChipCommon exists and
+ * advertises PMU support */
+ if (ccaps.pmu) {
if ((error = bhnd_generic_alloc_pmu(dev, child)))
return (error);
@@ -259,8 +274,24 @@ siba_alloc_pmu(device_t dev, device_t child)
return (0);
}
- /* This is a legacy PWRCTL chipset; we need to map all bhnd(4) bus PMU
- * to PWRCTL operations ourselves.*/
+ /*
+ * This is either a legacy PWRCTL chipset, or the device does not
+ * support dynamic clock control.
+ *
+ * We need to map all bhnd(4) bus PMU to PWRCTL or no-op operations.
+ */
+ if (ccaps.pwr_ctrl) {
+ pmu_state = SIBA_PMU_PWRCTL;
+ pwrctl = bhnd_retain_provider(child, BHND_SERVICE_PWRCTL);
+ if (pwrctl == NULL) {
+ device_printf(dev, "PWRCTL not found\n");
+ return (ENODEV);
+ }
+ } else {
+ pmu_state = SIBA_PMU_FIXED;
+ pwrctl = NULL;
+ }
+
SIBA_LOCK(sc);
/* Per-core PMU state already allocated? */
@@ -270,8 +301,8 @@ siba_alloc_pmu(device_t dev, device_t child)
}
/* Update the child's PMU allocation state, and transfer ownership of
- * the PWRCTL provider reference */
- dinfo->pmu_state = SIBA_PMU_PWRCTL;
+ * the PWRCTL provider reference (if any) */
+ dinfo->pmu_state = pmu_state;
dinfo->pmu.pwrctl = pwrctl;
SIBA_UNLOCK(sc);
@@ -324,6 +355,15 @@ siba_release_pmu(device_t dev, device_t child)
/* Release the provider reference */
bhnd_release_provider(child, pwrctl, BHND_SERVICE_PWRCTL);
return (0);
+
+ case SIBA_PMU_FIXED:
+ /* Clean up the child's PMU state */
+ KASSERT(dinfo->pmu.pwrctl == NULL,
+ ("PWRCTL reference with FIXED state"));
+
+ dinfo->pmu_state = SIBA_PMU_NONE;
+ dinfo->pmu.pwrctl = NULL;
+ SIBA_UNLOCK(sc);
}
panic("invalid PMU state: %d", dinfo->pmu_state);
@@ -363,6 +403,22 @@ siba_get_clock_latency(device_t dev, device_t child, b
SIBA_UNLOCK(sc);
return (error);
+
+ case SIBA_PMU_FIXED:
+ SIBA_UNLOCK(sc);
+
+ /* HT clock is always available, and incurs no transition
+ * delay. */
+ switch (clock) {
+ case BHND_CLOCK_HT:
+ *latency = 0;
+ return (0);
+
+ default:
+ return (ENODEV);
+ }
+
+ return (ENODEV);
}
panic("invalid PMU state: %d", dinfo->pmu_state);
@@ -401,6 +457,11 @@ siba_get_clock_freq(device_t dev, device_t child, bhnd
SIBA_UNLOCK(sc);
return (error);
+
+ case SIBA_PMU_FIXED:
+ SIBA_UNLOCK(sc);
+
+ return (ENODEV);
}
panic("invalid PMU state: %d", dinfo->pmu_state);
@@ -432,6 +493,7 @@ siba_request_ext_rsrc(device_t dev, device_t child, u_
return (bhnd_generic_request_ext_rsrc(dev, child, rsrc));
case SIBA_PMU_PWRCTL:
+ case SIBA_PMU_FIXED:
/* HW does not support per-core external resources */
SIBA_UNLOCK(sc);
return (ENODEV);
@@ -466,6 +528,7 @@ siba_release_ext_rsrc(device_t dev, device_t child, u_
return (bhnd_generic_release_ext_rsrc(dev, child, rsrc));
case SIBA_PMU_PWRCTL:
+ case SIBA_PMU_FIXED:
/* HW does not support per-core external resources */
SIBA_UNLOCK(sc);
return (ENODEV);
@@ -506,6 +569,22 @@ siba_request_clock(device_t dev, device_t child, bhnd_
SIBA_UNLOCK(sc);
return (error);
+
+ case SIBA_PMU_FIXED:
+ SIBA_UNLOCK(sc);
+
+ /* HT clock is always available, and fulfills any of the
+ * following clock requests */
+ switch (clock) {
+ case BHND_CLOCK_DYN:
+ case BHND_CLOCK_ILP:
+ case BHND_CLOCK_ALP:
+ case BHND_CLOCK_HT:
+ return (0);
+
+ default:
+ return (ENODEV);
+ }
}
panic("invalid PMU state: %d", dinfo->pmu_state);
@@ -537,6 +616,7 @@ siba_enable_clocks(device_t dev, device_t child, uint3
return (bhnd_generic_enable_clocks(dev, child, clocks));
case SIBA_PMU_PWRCTL:
+ case SIBA_PMU_FIXED:
SIBA_UNLOCK(sc);
/* All (supported) clocks are already enabled by default */
Modified: head/sys/dev/bhnd/siba/sibavar.h
==============================================================================
--- head/sys/dev/bhnd/siba/sibavar.h Tue Nov 28 00:41:17 2017 (r326300)
+++ head/sys/dev/bhnd/siba/sibavar.h Tue Nov 28 00:42:44 2017 (r326301)
@@ -194,6 +194,7 @@ typedef enum {
SIBA_PMU_NONE, /**< If the core has not yet allocated PMU state */
SIBA_PMU_BHND, /**< If standard bhnd(4) PMU support should be used */
SIBA_PMU_PWRCTL, /**< If legacy PWRCTL PMU support should be used */
+ SIBA_PMU_FIXED, /**< If legacy fixed (no-op) PMU support should be used */
} siba_pmu_state;
/**
Modified: head/sys/modules/bhnd/siba/Makefile
==============================================================================
--- head/sys/modules/bhnd/siba/Makefile Tue Nov 28 00:41:17 2017 (r326300)
+++ head/sys/modules/bhnd/siba/Makefile Tue Nov 28 00:42:44 2017 (r326301)
@@ -7,7 +7,8 @@ SRCS= siba.c siba_subr.c \
siba_erom.c
SRCS+= device_if.h bus_if.h
-SRCS+= bhnd_bus_if.h bhnd_erom_if.h \
- bhnd_pmu_if.h bhnd_pwrctl_if.h
+SRCS+= bhnd_bus_if.h bhnd_chipc_if.h \
+ bhnd_erom_if.h bhnd_pmu_if.h \
+ bhnd_pwrctl_if.h
.include <bsd.kmod.mk>
More information about the svn-src-all
mailing list