svn commit: r319704 - head/sys/arm/mv/armada38x

Zbigniew Bodek zbb at FreeBSD.org
Thu Jun 8 16:48:10 UTC 2017


Author: zbb
Date: Thu Jun  8 16:48:09 2017
New Revision: 319704
URL: https://svnweb.freebsd.org/changeset/base/319704

Log:
  Enable MBUS bridge configuration in mv_rtc driver
  
  This patch fixes sporadic problems with updating time
  with mv_rtc driver by configuring access to it via MBUS.
  For this purpose already existing second set of resources
  in rtc at 3800 node of Armada 38x DT is used.
  
  Submitted by: Dominik Ermel <der at semihalf.com>
  Obtained from: Semihalf
  Sponsored by: Stormshield
  Differential revision: https://reviews.freebsd.org/D10901

Modified:
  head/sys/arm/mv/armada38x/rtc.c

Modified: head/sys/arm/mv/armada38x/rtc.c
==============================================================================
--- head/sys/arm/mv/armada38x/rtc.c	Thu Jun  8 16:46:38 2017	(r319703)
+++ head/sys/arm/mv/armada38x/rtc.c	Thu Jun  8 16:48:09 2017	(r319704)
@@ -69,17 +69,30 @@ __FBSDID("$FreeBSD$");
 #define	RTC_STATUS_ALARM1_MASK	0x1
 #define	RTC_STATUS_ALARM2_MASK	0x2
 
-#define	MV_RTC_LOCK(sc)		mtx_lock(&(sc)->mutex)
-#define	MV_RTC_UNLOCK(sc)	mtx_unlock(&(sc)->mutex)
+#define	MV_RTC_LOCK(sc)		mtx_lock_spin(&(sc)->mutex)
+#define	MV_RTC_UNLOCK(sc)	mtx_unlock_spin(&(sc)->mutex)
 
+#define	RTC_BRIDGE_TIMING_CTRL		0x0
+#define	RTC_WRCLK_PERIOD_SHIFT			0
+#define	RTC_WRCLK_PERIOD_MASK			0x00000003FF
+#define	RTC_WRCLK_PERIOD_MAX			0x3FF
+#define	RTC_READ_OUTPUT_DELAY_SHIFT		26
+#define	RTC_READ_OUTPUT_DELAY_MASK		0x007C000000
+#define	RTC_READ_OUTPUT_DELAY_MAX		0x1F
+
+#define	RTC_RES		0
+#define	RTC_SOC_RES	1
+
+
 static struct resource_spec res_spec[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },
 	{ -1, 0 }
 };
 
 struct mv_rtc_softc {
 	device_t	dev;
-	struct resource	*res;
+	struct resource	*res[2];
 	struct mtx	mutex;
 };
 
@@ -90,9 +103,11 @@ static int mv_rtc_detach(device_t dev);
 static int mv_rtc_gettime(device_t dev, struct timespec *ts);
 static int mv_rtc_settime(device_t dev, struct timespec *ts);
 
-static uint32_t mv_rtc_reg_read(struct mv_rtc_softc *sc, bus_size_t off);
-static int mv_rtc_reg_write(struct mv_rtc_softc *sc, bus_size_t off,
+static inline uint32_t mv_rtc_reg_read(struct mv_rtc_softc *sc,
+    bus_size_t off);
+static inline int mv_rtc_reg_write(struct mv_rtc_softc *sc, bus_size_t off,
     uint32_t val);
+static inline void mv_rtc_configure_bus(struct mv_rtc_softc *sc);
 
 static device_method_t mv_rtc_methods[] = {
 	DEVMETHOD(device_probe,		mv_rtc_probe),
@@ -180,14 +195,16 @@ mv_rtc_attach(device_t dev)
 
 	clock_register(dev, RTC_RES_US);
 
-	mtx_init(&sc->mutex, device_get_nameunit(dev), NULL, MTX_DEF);
+	mtx_init(&sc->mutex, device_get_nameunit(dev), NULL, MTX_SPIN);
 
-	ret = bus_alloc_resources(dev, res_spec, &sc->res);
+	ret = bus_alloc_resources(dev, res_spec, sc->res);
+
 	if (ret != 0) {
 		device_printf(dev, "could not allocate resources\n");
 		mtx_destroy(&sc->mutex);
 		return (ENXIO);
 	}
+	mv_rtc_configure_bus(sc);
 
 	return (0);
 }
@@ -201,7 +218,7 @@ mv_rtc_detach(device_t dev)
 
 	mtx_destroy(&sc->mutex);
 
-	bus_release_resources(dev, res_spec, &sc->res);
+	bus_release_resources(dev, res_spec, sc->res);
 
 	return (0);
 }
@@ -267,11 +284,11 @@ mv_rtc_settime(device_t dev, struct timespec *ts)
 	return (0);
 }
 
-static uint32_t
+static inline uint32_t
 mv_rtc_reg_read(struct mv_rtc_softc *sc, bus_size_t off)
 {
 
-	return (bus_read_4(sc->res, off));
+	return (bus_read_4(sc->res[RTC_RES], off));
 }
 
 /*
@@ -279,12 +296,24 @@ mv_rtc_reg_read(struct mv_rtc_softc *sc, bus_size_t of
  * register write to the RTC hard macro so that the required update
  * can occur without holding off the system bus
  */
-static int
+static inline int
 mv_rtc_reg_write(struct mv_rtc_softc *sc, bus_size_t off, uint32_t val)
 {
 
-	bus_write_4(sc->res, off, val);
+	bus_write_4(sc->res[RTC_RES], off, val);
 	DELAY(5);
 
 	return (0);
+}
+
+static inline void
+mv_rtc_configure_bus(struct mv_rtc_softc *sc)
+{
+	int val;
+
+	val = bus_read_4(sc->res[RTC_SOC_RES], RTC_BRIDGE_TIMING_CTRL);
+	val &= ~(RTC_WRCLK_PERIOD_MASK | RTC_READ_OUTPUT_DELAY_MASK);
+	val |= RTC_WRCLK_PERIOD_MAX << RTC_WRCLK_PERIOD_SHIFT;
+	val |= RTC_READ_OUTPUT_DELAY_MAX << RTC_READ_OUTPUT_DELAY_SHIFT;
+	bus_write_4(sc->res[RTC_SOC_RES], RTC_BRIDGE_TIMING_CTRL, val);
 }


More information about the svn-src-all mailing list