svn commit: r306376 - head/sys/arm/ti/cpsw
Luiz Otavio O Souza
loos at FreeBSD.org
Tue Sep 27 18:19:31 UTC 2016
Author: loos
Date: Tue Sep 27 18:19:29 2016
New Revision: 306376
URL: https://svnweb.freebsd.org/changeset/base/306376
Log:
Add a sysctl to control the interrupt pacing on AM335x integrated switch.
The hardware can be set to limit the number of interrupts from 2 to 63
interrupts per ms.
To keep the compatibility with the TI documentation the sysctl take the
interval between the interrupts pulses: 16~500 us.
Sponsored by: Rubicon Communications, LLC (Netgate)
Modified:
head/sys/arm/ti/cpsw/if_cpsw.c
head/sys/arm/ti/cpsw/if_cpswreg.h
head/sys/arm/ti/cpsw/if_cpswvar.h
Modified: head/sys/arm/ti/cpsw/if_cpsw.c
==============================================================================
--- head/sys/arm/ti/cpsw/if_cpsw.c Tue Sep 27 18:08:38 2016 (r306375)
+++ head/sys/arm/ti/cpsw/if_cpsw.c Tue Sep 27 18:19:29 2016 (r306376)
@@ -583,6 +583,11 @@ cpsw_init(struct cpsw_softc *sc)
struct cpsw_slot *slot;
uint32_t reg;
+ /* Disable the interrupt pacing. */
+ reg = cpsw_read_4(sc, CPSW_WR_INT_CONTROL);
+ reg &= ~(CPSW_WR_INT_PACE_EN | CPSW_WR_INT_PRESCALE_MASK);
+ cpsw_write_4(sc, CPSW_WR_INT_CONTROL, reg);
+
/* Clear ALE */
cpsw_write_4(sc, CPSW_ALE_CONTROL, CPSW_ALE_CTL_CLEAR_TBL);
@@ -2492,6 +2497,51 @@ cpsw_stat_attached(SYSCTL_HANDLER_ARGS)
}
static int
+cpsw_intr_coalesce(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ struct cpsw_softc *sc;
+ uint32_t ctrl, intr_per_ms;
+
+ sc = (struct cpsw_softc *)arg1;
+ error = sysctl_handle_int(oidp, &sc->coal_us, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+
+ ctrl = cpsw_read_4(sc, CPSW_WR_INT_CONTROL);
+ ctrl &= ~(CPSW_WR_INT_PACE_EN | CPSW_WR_INT_PRESCALE_MASK);
+ if (sc->coal_us == 0) {
+ /* Disable the interrupt pace hardware. */
+ cpsw_write_4(sc, CPSW_WR_INT_CONTROL, ctrl);
+ cpsw_write_4(sc, CPSW_WR_C_RX_IMAX(0), 0);
+ cpsw_write_4(sc, CPSW_WR_C_TX_IMAX(0), 0);
+ return (0);
+ }
+
+ if (sc->coal_us > CPSW_WR_C_IMAX_US_MAX)
+ sc->coal_us = CPSW_WR_C_IMAX_US_MAX;
+ if (sc->coal_us < CPSW_WR_C_IMAX_US_MIN)
+ sc->coal_us = CPSW_WR_C_IMAX_US_MIN;
+ intr_per_ms = 1000 / sc->coal_us;
+ /* Just to make sure... */
+ if (intr_per_ms > CPSW_WR_C_IMAX_MAX)
+ intr_per_ms = CPSW_WR_C_IMAX_MAX;
+ if (intr_per_ms < CPSW_WR_C_IMAX_MIN)
+ intr_per_ms = CPSW_WR_C_IMAX_MIN;
+
+ /* Set the prescale to produce 4us pulses from the 125 Mhz clock. */
+ ctrl |= (125 * 4) & CPSW_WR_INT_PRESCALE_MASK;
+
+ /* Enable the interrupt pace hardware. */
+ cpsw_write_4(sc, CPSW_WR_C_RX_IMAX(0), intr_per_ms);
+ cpsw_write_4(sc, CPSW_WR_C_TX_IMAX(0), intr_per_ms);
+ ctrl |= CPSW_WR_INT_C0_RX_PULSE | CPSW_WR_INT_C0_TX_PULSE;
+ cpsw_write_4(sc, CPSW_WR_INT_CONTROL, ctrl);
+
+ return (0);
+}
+
+static int
cpsw_stat_uptime(SYSCTL_HANDLER_ARGS)
{
struct cpsw_softc *swsc;
@@ -2576,6 +2626,10 @@ cpsw_add_sysctls(struct cpsw_softc *sc)
CTLTYPE_UINT | CTLFLAG_RD, sc, 0, cpsw_stat_attached, "IU",
"Time since driver attach");
+ SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "intr_coalesce_us",
+ CTLTYPE_UINT | CTLFLAG_RW, sc, 0, cpsw_intr_coalesce, "IU",
+ "minimum time between interrupts");
+
node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "ports",
CTLFLAG_RD, NULL, "CPSW Ports Statistics");
ports_parent = SYSCTL_CHILDREN(node);
Modified: head/sys/arm/ti/cpsw/if_cpswreg.h
==============================================================================
--- head/sys/arm/ti/cpsw/if_cpswreg.h Tue Sep 27 18:08:38 2016 (r306375)
+++ head/sys/arm/ti/cpsw/if_cpswreg.h Tue Sep 27 18:19:29 2016 (r306376)
@@ -138,6 +138,17 @@
#define CPSW_WR_SOFT_RESET (CPSW_WR_OFFSET + 0x04)
#define CPSW_WR_CONTROL (CPSW_WR_OFFSET + 0x08)
#define CPSW_WR_INT_CONTROL (CPSW_WR_OFFSET + 0x0c)
+#define CPSW_WR_INT_C0_RX_PULSE (1 << 16)
+#define CPSW_WR_INT_C0_TX_PULSE (1 << 17)
+#define CPSW_WR_INT_C1_RX_PULSE (1 << 18)
+#define CPSW_WR_INT_C1_TX_PULSE (1 << 19)
+#define CPSW_WR_INT_C2_RX_PULSE (1 << 20)
+#define CPSW_WR_INT_C2_TX_PULSE (1 << 21)
+#define CPSW_WR_INT_PACE_EN \
+ (CPSW_WR_INT_C0_RX_PULSE | CPSW_WR_INT_C0_TX_PULSE | \
+ CPSW_WR_INT_C1_RX_PULSE | CPSW_WR_INT_C1_TX_PULSE | \
+ CPSW_WR_INT_C2_RX_PULSE | CPSW_WR_INT_C2_TX_PULSE)
+#define CPSW_WR_INT_PRESCALE_MASK 0xfff
#define CPSW_WR_C_RX_THRESH_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x10)
#define CPSW_WR_C_RX_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x14)
#define CPSW_WR_C_TX_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x18)
@@ -151,6 +162,13 @@
#define CPSW_WR_C_MISC_HOST_PEND (1 << 2)
#define CPSW_WR_C_MISC_MDIOLINK (1 << 1)
#define CPSW_WR_C_MISC_MDIOUSER (1 << 0)
+#define CPSW_WR_C_RX_IMAX(p) (CPSW_WR_OFFSET + (0x08 * (p)) + 0x70)
+#define CPSW_WR_C_TX_IMAX(p) (CPSW_WR_OFFSET + (0x08 * (p)) + 0x74)
+#define CPSW_WR_C_IMAX_MASK 0x3f
+#define CPSW_WR_C_IMAX_MAX 63
+#define CPSW_WR_C_IMAX_MIN 2
+#define CPSW_WR_C_IMAX_US_MAX 500
+#define CPSW_WR_C_IMAX_US_MIN 16
#define CPSW_CPPI_RAM_OFFSET 0x2000
#define CPSW_CPPI_RAM_SIZE 0x2000
Modified: head/sys/arm/ti/cpsw/if_cpswvar.h
==============================================================================
--- head/sys/arm/ti/cpsw/if_cpswvar.h Tue Sep 27 18:08:38 2016 (r306375)
+++ head/sys/arm/ti/cpsw/if_cpswvar.h Tue Sep 27 18:19:29 2016 (r306376)
@@ -80,6 +80,7 @@ struct cpsw_softc {
phandle_t node;
struct bintime attach_uptime; /* system uptime when attach happened. */
struct cpsw_port port[2];
+ unsigned coal_us;
/* RX and TX buffer tracking */
struct cpsw_queue rx, tx;
More information about the svn-src-all
mailing list