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