summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/octeon/dev/octdwctwo.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/sys/arch/octeon/dev/octdwctwo.c b/sys/arch/octeon/dev/octdwctwo.c
index cf8b797c4ff..b28c240c889 100644
--- a/sys/arch/octeon/dev/octdwctwo.c
+++ b/sys/arch/octeon/dev/octdwctwo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: octdwctwo.c,v 1.11 2017/02/15 14:44:20 visa Exp $ */
+/* $OpenBSD: octdwctwo.c,v 1.12 2019/07/28 12:57:09 visa Exp $ */
/*
* Copyright (c) 2015 Masao Uebayashi <uebayasi@tombiinc.com>
@@ -51,6 +51,7 @@ struct octdwctwo_softc {
int octdwctwo_match(struct device *, void *, void *);
void octdwctwo_attach(struct device *, struct device *,
void *);
+int octdwctwo_activate(struct device *, int);
int octdwctwo_set_dma_addr(void *, dma_addr_t, int);
u_int64_t octdwctwo_reg2_rd(struct octdwctwo_softc *, bus_size_t);
void octdwctwo_reg2_wr(struct octdwctwo_softc *, bus_size_t,
@@ -67,6 +68,7 @@ void octdwctwo_write_4(bus_space_tag_t, bus_space_handle_t,
const struct cfattach octdwctwo_ca = {
sizeof(struct octdwctwo_softc), octdwctwo_match, octdwctwo_attach,
+ NULL, octdwctwo_activate
};
struct cfdriver dwctwo_cd = {
@@ -232,6 +234,41 @@ octdwctwo_attach(struct device *parent, struct device *self, void *aux)
}
int
+octdwctwo_activate(struct device *self, int act)
+{
+ struct octdwctwo_softc *sc = (struct octdwctwo_softc *)self;
+ uint64_t clk;
+ int rv = 0;
+
+ switch (act) {
+ case DVACT_POWERDOWN:
+ /*
+ * Put the controller into reset mode.
+ * It appears necessary to hold this state for a moment.
+ * Otherwise subsequent attempts to reinitialize the controller
+ * may fail because of hanging or trapping access
+ * of DWC2 core registers.
+ */
+ clk = bus_space_read_8(sc->sc_bust, sc->sc_regh,
+ USBN_CLK_CTL_OFFSET);
+ clk |= USBN_CLK_CTL_POR;
+ clk |= USBN_CLK_CTL_HCLK_RST;
+ clk |= USBN_CLK_CTL_ENABLE;
+ clk &= ~USBN_CLK_CTL_HRST;
+ clk &= ~USBN_CLK_CTL_PRST;
+ bus_space_write_8(sc->sc_bust, sc->sc_regh,
+ USBN_CLK_CTL_OFFSET, clk);
+ (void)bus_space_read_8(sc->sc_bust, sc->sc_regh,
+ USBN_CLK_CTL_OFFSET);
+ delay(50000);
+ break;
+ default:
+ break;
+ }
+ return rv;
+}
+
+int
octdwctwo_set_dma_addr(void *data, dma_addr_t dma_addr, int ch)
{
struct octdwctwo_softc *sc = data;