#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: octeon_asx.c,v 1.5 2021/01/04 17:22:59 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kmem.h>
#include <mips/cavium/octeonvar.h>
#include <mips/cavium/dev/octeon_asxreg.h>
#include <mips/cavium/dev/octeon_asxvar.h>
void
octasx_init(struct octasx_attach_args *aa, struct octasx_softc **rsc)
{
struct octasx_softc *sc;
int status;
sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
if (sc == NULL)
panic("can't allocate memory: %s", __func__);
sc->sc_port = aa->aa_port;
sc->sc_regt = aa->aa_regt;
status = bus_space_map(sc->sc_regt, ASX0_BASE, ASX0_SIZE, 0,
&sc->sc_regh);
if (status != 0)
panic("can't map %s space", "asx register");
*rsc = sc;
}
#define _ASX_RD8(sc, off) \
bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
#define _ASX_WR8(sc, off, v) \
bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))
static int octasx_enable_tx(struct octasx_softc *, int);
static int octasx_enable_rx(struct octasx_softc *, int);
int
octasx_enable(struct octasx_softc *sc, int enable)
{
octasx_enable_tx(sc, enable);
octasx_enable_rx(sc, enable);
return 0;
}
static int
octasx_enable_tx(struct octasx_softc *sc, int enable)
{
uint64_t asx_tx_port;
asx_tx_port = _ASX_RD8(sc, ASX0_TX_PRT_EN_OFFSET);
if (enable)
SET(asx_tx_port, __BIT(sc->sc_port));
else
CLR(asx_tx_port, __BIT(sc->sc_port));
_ASX_WR8(sc, ASX0_TX_PRT_EN_OFFSET, asx_tx_port);
return 0;
}
static int
octasx_enable_rx(struct octasx_softc *sc, int enable)
{
uint64_t asx_rx_port;
asx_rx_port = _ASX_RD8(sc, ASX0_RX_PRT_EN_OFFSET);
if (enable)
SET(asx_rx_port, __BIT(sc->sc_port));
else
CLR(asx_rx_port, __BIT(sc->sc_port));
_ASX_WR8(sc, ASX0_RX_PRT_EN_OFFSET, asx_rx_port);
return 0;
}
int
octasx_clk_set(struct octasx_softc *sc, int tx_setting, int rx_setting)
{
_ASX_WR8(sc, ASX0_TX_CLK_SET0_OFFSET + 8 * sc->sc_port, tx_setting);
_ASX_WR8(sc, ASX0_RX_CLK_SET0_OFFSET + 8 * sc->sc_port, rx_setting);
return 0;
}