Module Name: src
Committed By: macallan
Date: Tue Jun 13 10:09:32 UTC 2023
Modified Files:
src/sys/arch/sparc/dev: sx.c sxvar.h
Log Message:
add counter to periodically drain the instruction queue in order to avoid
stalling the MBus during long SX operations
adapted from xf86-video-suncg14
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/sparc/dev/sx.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/sparc/dev/sxvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/sparc/dev/sx.c
diff -u src/sys/arch/sparc/dev/sx.c:1.6 src/sys/arch/sparc/dev/sx.c:1.7
--- src/sys/arch/sparc/dev/sx.c:1.6 Thu Apr 13 13:07:48 2023
+++ src/sys/arch/sparc/dev/sx.c Tue Jun 13 10:09:31 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: sx.c,v 1.6 2023/04/13 13:07:48 macallan Exp $ */
+/* $NetBSD: sx.c,v 1.7 2023/06/13 10:09:31 macallan Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sx.c,v 1.6 2023/04/13 13:07:48 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sx.c,v 1.7 2023/06/13 10:09:31 macallan Exp $");
#include "locators.h"
@@ -84,6 +84,7 @@ sx_attach(device_t parent, device_t self
sc->sc_dev = self;
sc->sc_tag = ma->ma_bustag;
sc->sc_uregs = ma->ma_paddr + 0x1000;
+ sc->sc_cnt = 0;
if (bus_space_map(sc->sc_tag, ma->ma_paddr, 0x1000, 0, &sc->sc_regh)) {
aprint_error_dev(self, "failed to map registers\n");
Index: src/sys/arch/sparc/dev/sxvar.h
diff -u src/sys/arch/sparc/dev/sxvar.h:1.4 src/sys/arch/sparc/dev/sxvar.h:1.5
--- src/sys/arch/sparc/dev/sxvar.h:1.4 Fri Mar 1 02:30:42 2019
+++ src/sys/arch/sparc/dev/sxvar.h Tue Jun 13 10:09:31 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: sxvar.h,v 1.4 2019/03/01 02:30:42 macallan Exp $ */
+/* $NetBSD: sxvar.h,v 1.5 2023/06/13 10:09:31 macallan Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -32,11 +32,14 @@
#ifndef SXVAR_H
#define SXVAR_H
+#include <sparc/dev/sxreg.h>
+
struct sx_softc {
device_t sc_dev;
bus_addr_t sc_uregs;
bus_space_tag_t sc_tag;
bus_space_handle_t sc_regh;
+ int sc_cnt;
};
static inline void
@@ -51,6 +54,26 @@ sx_read(struct sx_softc *sc, int addr)
return bus_space_read_4(sc->sc_tag, sc->sc_regh, addr);
}
+/*
+ * to be used before issuing SX instructions
+ * this will periodically allow the instruction queue to drain in order
+ * to avoid excessive MBus relinquish & retry cycles during long SX ops
+ * which may cause us to lose interrupts
+ */
+static inline void
+sx_wait(struct sx_softc *sc)
+{
+ uint32_t reg;
+ if (sc->sc_cnt > 6) {
+ do {
+ reg = bus_space_read_4(sc->sc_tag, sc->sc_regh,
+ SX_CONTROL_STATUS);
+ } while ((reg & SX_MT) == 0);
+ sc->sc_cnt = 0;
+ } else
+ sc->sc_cnt++;
+}
+
void sx_dump(void);
#endif