code:
/*	$OpenBSD: cn30xxpow.c,v 1.7 2014/08/11 18:56:49 miod Exp $	*/

/*
 * Copyright (c) 2007 Internet Initiative Japan, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/kernel.h>				/* hz */
#include <sys/malloc.h>

#include <machine/bus.h>
#include <machine/octeonvar.h>

#include <octeon/dev/iobusvar.h>
#include <octeon/dev/cn30xxciureg.h>	/* XXX */
#include <octeon/dev/cn30xxpowreg.h>
#include <octeon/dev/cn30xxpowvar.h>

extern int ipflow_fastforward_disable_flags;

struct cn30xxpow_intr_handle {
	void				*pi_ih;
	struct cn30xxpow_softc		*pi_sc;
	int				pi_group;
	void				(*pi_cb)(void *, uint64_t *);
	void				*pi_data;

#ifdef OCTEON_ETH_DEBUG
#define	_EV_PER_N	32	/* XXX */
#define	_EV_IVAL_N	32	/* XXX */
	int				pi_first;
	struct timeval			pi_last;
#endif
};

void	cn30xxpow_bootstrap(struct octeon_config *);

#ifdef OCTEON_ETH_DEBUG
void	cn30xxpow_intr_rml(void *);

void	cn30xxpow_intr_debug_init(struct cn30xxpow_intr_handle *, int);
void	cn30xxpow_intr_work_debug_ival(struct cn30xxpow_softc *,
	    struct cn30xxpow_intr_handle *);
#endif
void	cn30xxpow_init(struct cn30xxpow_softc *);
void	cn30xxpow_init_regs(struct cn30xxpow_softc *);
int	cn30xxpow_tag_sw_poll(void);
void	cn30xxpow_tag_sw_wait(void);
void	cn30xxpow_config_int_pc(struct cn30xxpow_softc *, int);
void	cn30xxpow_config_int(struct cn30xxpow_softc *, int,
	    uint64_t, uint64_t, uint64_t);
void	cn30xxpow_intr_work(struct cn30xxpow_softc *,
	    struct cn30xxpow_intr_handle *, int);
int	cn30xxpow_intr(void *);

#ifdef OCTEON_ETH_DEBUG
void	cn30xxpow_dump(void);
#endif

/* XXX */
struct cn30xxpow_softc	cn30xxpow_softc;

#ifdef OCTEON_ETH_DEBUG
struct cn30xxpow_softc *__cn30xxpow_softc;
#endif

/*
 * XXX: parameter tuning is needed: see files.octeon
 */
#ifndef OCTEON_ETH_RING_MAX
#define OCTEON_ETH_RING_MAX 512
#endif
#ifndef OCTEON_ETH_RING_MIN
#define OCTEON_ETH_RING_MIN 1
#endif

#ifdef OCTEON_ETH_INTR_FEEDBACK_RING
int max_recv_cnt = OCTEON_ETH_RING_MAX;
int min_recv_cnt = OCTEON_ETH_RING_MIN;
int recv_cnt = OCTEON_ETH_RING_MIN;
int int_rate = 1;
#else
/* infinity */
int max_recv_cnt = 0;
int min_recv_cnt = 0;
int recv_cnt = 0;
#endif

/* -------------------------------------------------------------------------- */

/* ---- operation primitive functions */

/* 5.11.1 Load Operations */

/* 5.11.2 IOBDMA Operations */

/* 5.11.3 Store Operations */

/* -------------------------------------------------------------------------- */

/* ---- utility functions */

void
cn30xxpow_work_request_async(uint64_t scraddr, uint64_t wait)
{
        cn30xxpow_ops_get_work_iobdma(scraddr, wait);
}

uint64_t *
cn30xxpow_work_response_async(uint64_t scraddr)
{
	uint64_t result;

	mips_sync();
	result = octeon_cvmseg_read_8(scraddr);

	return (result & POW_IOBDMA_GET_WORK_RESULT_NO_WORK) ?
	    NULL :
	    (uint64_t *)PHYS_TO_XKPHYS(
		result & POW_IOBDMA_GET_WORK_RESULT_ADDR, CCA_CACHED);
}

/* ---- status by coreid */

static inline uint64_t
cn30xxpow_status_by_coreid_pend_tag(int coreid)
{
	return cn30xxpow_ops_pow_status(coreid, 0, 0, 0);
}

static inline uint64_t
cn30xxpow_status_by_coreid_pend_wqp(int coreid)
{
	return cn30xxpow_ops_pow_status(coreid, 0, 0, 1);
}

static inline uint64_t
cn30xxpow_status_by_coreid_cur_tag_next(int coreid)
{
	return cn30xxpow_ops_pow_status(coreid, 0, 1, 0);
}

static inline uint64_t
cn30xxpow_status_by_coreid_cur_tag_prev(int coreid)
{
	return cn30xxpow_ops_pow_status(coreid, 1, 1, 0);
}

static inline uint64_t
cn30xxpow_status_by_coreid_cur_wqp_next(int coreid)
{
	return cn30xxpow_ops_pow_status(coreid, 0, 1, 1);
}

static inline uint64_t
cn30xxpow_status_by_coreid_cur_wqp_prev(int coreid)
{
	return cn30xxpow_ops_pow_status(coreid, 1, 1, 1);
}

/* ---- status by index */

static inline uint64_t
cn30xxpow_status_by_index_tag(int index)
{
	return cn30xxpow_ops_pow_memory(index, 0, 0);
}

static inline uint64_t
cn30xxpow_status_by_index_wqp(int index)
{
	return cn30xxpow_ops_pow_memory(index, 0, 1);
}

static inline uint64_t
cn30xxpow_status_by_index_desched(int index)
{
	return cn30xxpow_ops_pow_memory(index, 1, 0);
}

/* ---- status by qos level */

static inline uint64_t
cn30xxpow_status_by_qos_free_loc(int qos)
{
	return cn30xxpow_ops_pow_idxptr(qos, 0, 0);
}

/* ---- status by desched group */

static inline uint64_t
cn30xxpow_status_by_grp_nosched_des(int grp)
{
	return cn30xxpow_ops_pow_idxptr(grp, 0, 1);
}

/* ---- status by memory input queue */

static inline uint64_t
cn30xxpow_status_by_queue_remote_head(int queue)
{
	return cn30xxpow_ops_pow_idxptr(queue, 1, 0);
}

static inline uint64_t
cn30xxpow_status_by_queue_remote_tail(int queue)
{
	return cn30xxpow_ops_pow_idxptr(queue, 1, 0);
}

/* ---- tag switch */

/*
 * "RDHWR rt, $30" returns:
 *	0 => pending bit is set
 *	1 => pending bit is clear
 */

/* return 1 if pending bit is clear (ready) */
int
cn30xxpow_tag_sw_poll(void)
{
	uint64_t result;

	__asm volatile (
		"	.set	push		\n"
		"	.set	noreorder	\n"
		"	.set	arch=mips64r2	\n"
		"	rdhwr	%[result], $30	\n"
		"	.set	pop		\n"
		: [result]"=r"(result)
	);
	return (int)result;
}

void
cn30xxpow_tag_sw_wait(void)
{

	while (cn30xxpow_tag_sw_poll() == 0)
		continue;
}

/* -------------------------------------------------------------------------- */

/* ---- initialization and configuration */

void
cn30xxpow_bootstrap(struct octeon_config *mcp)
{
	struct cn30xxpow_softc *sc = &cn30xxpow_softc;

	sc->sc_regt = mcp->mc_iobus_bust;
	/* XXX */

	cn30xxpow_init(sc);

#ifdef OCTEON_ETH_DEBUG
	__cn30xxpow_softc = sc;
#endif

}

void
cn30xxpow_config_int(struct cn30xxpow_softc *sc, int group,
   uint64_t tc_thr, uint64_t ds_thr, uint64_t iq_thr)
{
	uint64_t wq_int_thr;

	wq_int_thr =
	    POW_WQ_INT_THRX_TC_EN |
	    (tc_thr << POW_WQ_INT_THRX_TC_THR_SHIFT) |
	    (ds_thr << POW_WQ_INT_THRX_DS_THR_SHIFT) |
	    (iq_thr << POW_WQ_INT_THRX_IQ_THR_SHIFT);
	_POW_WR8(sc, POW_WQ_INT_THR0_OFFSET + (group * 8), wq_int_thr);
}

/*
 * interrupt threshold configuration
 *
 * => DS / IQ
 *    => ...
 * => time counter threshold
 *    => unit is 1msec
 *    => each group can set timeout
 * => temporary disable bit
 *    => use CIU generic timer
 */

void
cn30xxpow_config(struct cn30xxpow_softc *sc, int group)
{

	cn30xxpow_config_int(sc, group,
	    0x0f,		/* TC */
	    0x00,		/* DS */
	    0x00);		/* IQ */
}

void *
cn30xxpow_intr_establish(int group, int level,
    void (*cb)(void *, uint64_t *), void (*fcb)(int*, int *, uint64_t, void *),
    void *data, char *what)
{
	struct cn30xxpow_intr_handle *pow_ih;

	KASSERT(group >= 0);
	KASSERT(group < 16);

	pow_ih = malloc(sizeof(*pow_ih), M_DEVBUF, M_NOWAIT);
	KASSERT(pow_ih != NULL);	/* XXX handle failure */

	pow_ih->pi_ih = octeon_intr_establish(
	    ffs64(CIU_INTX_SUM0_WORKQ_0) - 1 + group,
	    level,
	    cn30xxpow_intr, pow_ih, what);
	KASSERT(pow_ih->pi_ih != NULL);

	pow_ih->pi_sc = &cn30xxpow_softc;	/* XXX */
	pow_ih->pi_group = group;
	pow_ih->pi_cb = cb;
	pow_ih->pi_data = data;

#ifdef OCTEON_ETH_DEBUG
	cn30xxpow_intr_debug_init(pow_ih, group);
#endif
	return pow_ih;
}

#ifdef OCTEON_ETH_DEBUG

void
cn30xxpow_intr_debug_init(struct cn30xxpow_intr_handle *pow_ih, int group)
{
	pow_ih->pi_first = 1;

}
#endif

void
cn30xxpow_init(struct cn30xxpow_softc *sc)
{
	cn30xxpow_init_regs(sc);

	sc->sc_int_pc_base = 10000;
	cn30xxpow_config_int_pc(sc, sc->sc_int_pc_base);

#ifdef OCTEON_ETH_DEBUG
	cn30xxpow_error_int_enable(sc, 1);
#endif
}

void
cn30xxpow_init_regs(struct cn30xxpow_softc *sc)
{
	int status;

	status = bus_space_map(sc->sc_regt, POW_BASE, POW_SIZE, 0,
	    &sc->sc_regh);
	if (status != 0)
		panic("can't map %s space", "pow register");

#ifdef OCTEON_ETH_DEBUG
	_POW_WR8(sc, POW_ECC_ERR_OFFSET,
	    POW_ECC_ERR_IOP_IE | POW_ECC_ERR_RPE_IE |
	    POW_ECC_ERR_DBE_IE | POW_ECC_ERR_SBE_IE);
#endif
}

/* -------------------------------------------------------------------------- */

/* ---- interrupt handling */

#ifdef OCTEON_ETH_DEBUG
void
cn30xxpow_intr_work_debug_ival(struct cn30xxpow_softc *sc,
    struct cn30xxpow_intr_handle *pow_ih)
{
	struct timeval now;
	struct timeval ival;

	microtime(&now);
	if (__predict_false(pow_ih->pi_first == 1)) {
		pow_ih->pi_first = 0;
		goto stat_done;
	}
	timersub(&now, &pow_ih->pi_last, &ival);
	if (ival.tv_sec != 0)
		goto stat_done;	/* XXX */

stat_done:
	pow_ih->pi_last = now;	/* struct copy */
}
#endif

#ifdef OCTEON_ETH_DEBUG
#define _POW_INTR_WORK_DEBUG_IVAL(sc, ih) \
	    cn30xxpow_intr_work_debug_ival((sc), (ih))
#else
#define _POW_INTR_WORK_DEBUG_IVAL(sc, ih) \
	    do {} while (0)
#endif

/*
 * Interrupt handling by fixed count.
 *
 * XXX the fixed count (MAX_RX_CNT) could be changed dynamically?
 *
 * XXX this does not utilize "tag switch" very well
 */
/*
 * usually all packet recieve
 */
#define MAX_RX_CNT 0x7fffffff

void
cn30xxpow_intr_work(struct cn30xxpow_softc *sc,
    struct cn30xxpow_intr_handle *pow_ih, int max_recv_cnt)
{
	uint64_t *work;
	uint64_t count = 0;
	int recv_cnt = MAX_RX_CNT;

	/* s = splhigh(); */
	_POW_WR8(sc, POW_PP_GRP_MSK0_OFFSET, 1ULL << pow_ih->pi_group);

	if (max_recv_cnt > 0)
		recv_cnt = max_recv_cnt - 1;

	_POW_INTR_WORK_DEBUG_IVAL(sc, pow_ih);

	cn30xxpow_tag_sw_wait();
	cn30xxpow_work_request_async(OCTEON_CVMSEG_OFFSET(csm_pow_intr),
	    POW_NO_WAIT);

	for (count = 0; count < recv_cnt; count++) {
		work = (uint64_t *)cn30xxpow_work_response_async(
		    OCTEON_CVMSEG_OFFSET(csm_pow_intr));
		if (work == NULL)
			goto done;
		cn30xxpow_tag_sw_wait();
		cn30xxpow_work_request_async(
		    OCTEON_CVMSEG_OFFSET(csm_pow_intr), POW_NO_WAIT);
		(*pow_ih->pi_cb)(pow_ih->pi_data, work);
	}

	work = (uint64_t *)cn30xxpow_work_response_async(
	    OCTEON_CVMSEG_OFFSET(csm_pow_intr));
	if (work == NULL)
		goto done;

	(*pow_ih->pi_cb)(pow_ih->pi_data, work);
	count++;

done:
	;
	/* KASSERT(work == NULL); */
	/* KASSERT(count > 0); */

	/* _POW_WR8(sc, POW_PP_GRP, 0)ULL; */
	/* splx(s); */
}

int
cn30xxpow_intr(void *data)
{
	struct cn30xxpow_intr_handle *pow_ih = data;
	struct cn30xxpow_softc *sc = pow_ih->pi_sc;
	uint64_t wq_int_mask = 0x1ULL << pow_ih->pi_group;

#if 0
	if (ipflow_fastforward_disable_flags == 0)
		cn30xxpow_intr_work(sc, pow_ih, -1);
	else
		cn30xxpow_intr_work(sc, pow_ih, recv_cnt);
#else
	cn30xxpow_intr_work(sc, pow_ih, recv_cnt);
#endif

	_POW_WR8(sc, POW_WQ_INT_OFFSET, wq_int_mask << POW_WQ_INT_WQ_INT_SHIFT);
	return 1;
}

/* -------------------------------------------------------------------------- */

/* ---- debug configuration */

#ifdef OCTEON_ETH_DEBUG

void
cn30xxpow_error_int_enable(void *data, int enable)
{
	struct cn30xxpow_softc *sc = data;
	uint64_t pow_error_int_xxx;

	pow_error_int_xxx =
	    POW_ECC_ERR_IOP | POW_ECC_ERR_RPE |
	    POW_ECC_ERR_DBE | POW_ECC_ERR_SBE;
	_POW_WR8(sc, POW_ECC_ERR_OFFSET, pow_error_int_xxx);
	_POW_WR8(sc, POW_ECC_ERR_OFFSET, enable ? pow_error_int_xxx : 0);
}

uint64_t
cn30xxpow_error_int_summary(void *data)
{
	struct cn30xxpow_softc *sc = data;
	uint64_t summary;

	summary = _POW_RD8(sc, POW_ECC_ERR_OFFSET);
	_POW_WR8(sc, POW_ECC_ERR_OFFSET, summary);
	return summary;
}

#endif

/* -------------------------------------------------------------------------- */

/* ---- debug counter */

#ifdef OCTEON_ETH_DEBUG
int	cn30xxpow_intr_rml_verbose;

void
cn30xxpow_intr_rml(void *arg)
{
	struct cn30xxpow_softc *sc;
	uint64_t reg;

	sc = __cn30xxpow_softc;
	KASSERT(sc != NULL);
	reg = cn30xxpow_error_int_summary(sc);
	if (cn30xxpow_intr_rml_verbose)
		printf("%s: POW_ECC_ERR=0x%016llx\n", __func__, reg);
}
#endif

/* -------------------------------------------------------------------------- */

/* ---- debug dump */

#ifdef OCTEON_ETH_DEBUG

void	cn30xxpow_dump_reg(void);
void	cn30xxpow_dump_ops(void);

void
cn30xxpow_dump(void)
{
	cn30xxpow_dump_reg();
	cn30xxpow_dump_ops();
}

/* ---- register dump */

struct cn30xxpow_dump_reg_entry {
	const char *name;
	size_t offset;
};

#define	_ENTRY(x)	{ #x, x##_OFFSET }
#define	_ENTRY_0_7(x) \
	_ENTRY(x## 0), _ENTRY(x## 1), _ENTRY(x## 2), _ENTRY(x## 3), \
	_ENTRY(x## 4), _ENTRY(x## 5), _ENTRY(x## 6), _ENTRY(x## 7)
#define	_ENTRY_0_15(x) \
	_ENTRY(x## 0), _ENTRY(x## 1), _ENTRY(x## 2), _ENTRY(x## 3), \
	_ENTRY(x## 4), _ENTRY(x## 5), _ENTRY(x## 6), _ENTRY(x## 7), \
	_ENTRY(x## 8), _ENTRY(x## 9), _ENTRY(x##10), _ENTRY(x##11), \
	_ENTRY(x##12), _ENTRY(x##13), _ENTRY(x##14), _ENTRY(x##15)

const struct cn30xxpow_dump_reg_entry cn30xxpow_dump_reg_entries[] = {
	_ENTRY		(POW_PP_GRP_MSK0),
	_ENTRY		(POW_PP_GRP_MSK1),
	_ENTRY_0_15	(POW_WQ_INT_THR),
	_ENTRY_0_15	(POW_WQ_INT_CNT),
	_ENTRY_0_7	(POW_QOS_THR),
	_ENTRY_0_7	(POW_QOS_RND),
	_ENTRY		(POW_WQ_INT),
	_ENTRY		(POW_WQ_INT_PC),
	_ENTRY		(POW_NW_TIM),
	_ENTRY		(POW_ECC_ERR),
	_ENTRY		(POW_NOS_CNT),
	_ENTRY_0_15	(POW_WS_PC),
	_ENTRY_0_7	(POW_WA_PC),
	_ENTRY_0_7	(POW_IQ_CNT),
	_ENTRY		(POW_WA_COM_PC),
	_ENTRY		(POW_IQ_COM_CNT),
	_ENTRY		(POW_TS_PC),
	_ENTRY		(POW_DS_PC),
	_ENTRY		(POW_BIST_STAT)
};

#undef _ENTRY

void
cn30xxpow_dump_reg(void)
{
	struct cn30xxpow_softc *sc = __cn30xxpow_softc;
	const struct cn30xxpow_dump_reg_entry *entry;
	uint64_t tmp;
	int i;

	for (i = 0; i < (int)nitems(cn30xxpow_dump_reg_entries); i++) {
		entry = &cn30xxpow_dump_reg_entries[i];
		tmp = _POW_RD8(sc, entry->offset);
		printf("\t%-24s: %16llx\n", entry->name, tmp);
	}
}

/* ---- operations dump */

struct cn30xxpow_dump_ops_entry {
	const char *name;
	uint64_t (*func)(int);
};

void	cn30xxpow_dump_ops_coreid(int);
void	cn30xxpow_dump_ops_index(int);
void	cn30xxpow_dump_ops_qos(int);
void	cn30xxpow_dump_ops_grp(int);
void	cn30xxpow_dump_ops_queue(int);
void	cn30xxpow_dump_ops_common(const struct cn30xxpow_dump_ops_entry *,
	    size_t, const char *, int);

#define	_ENTRY_COMMON(name, prefix, x, y) \
	{ #name "_" #x, cn30xxpow_status_by_##name##_##x }

const struct cn30xxpow_dump_ops_entry cn30xxpow_dump_ops_coreid_entries[] = {
#define	_ENTRY(x, y)	_ENTRY_COMMON(coreid, POW_STATUS_LOAD_RESULT, x, y)
	_ENTRY(pend_tag, PEND_TAG),
	_ENTRY(pend_wqp, PEND_WQP),
	_ENTRY(cur_tag_next, CUR_TAG_NEXT),
	_ENTRY(cur_tag_prev, CUR_TAG_PREV),
	_ENTRY(cur_wqp_next, CUR_WQP_NEXT),
	_ENTRY(cur_wqp_prev, CUR_WQP_PREV)
#undef _ENTRY
};

const struct cn30xxpow_dump_ops_entry cn30xxpow_dump_ops_index_entries[] = {
#define	_ENTRY(x, y)	_ENTRY_COMMON(index, POW_MEMORY_LOAD_RESULT, x, y)
	_ENTRY(tag, TAG),
	_ENTRY(wqp, WQP),
	_ENTRY(desched, DESCHED)
#undef _ENTRY
};

const struct cn30xxpow_dump_ops_entry cn30xxpow_dump_ops_qos_entries[] = {
#define	_ENTRY(x, y)	_ENTRY_COMMON(qos, POW_IDXPTR_LOAD_RESULT_QOS, x, y)
	_ENTRY(free_loc, FREE_LOC)
#undef _ENTRY
};

const struct cn30xxpow_dump_ops_entry cn30xxpow_dump_ops_grp_entries[] = {
#define	_ENTRY(x, y)	_ENTRY_COMMON(grp, POW_IDXPTR_LOAD_RESULT_GRP, x, y)
	_ENTRY(nosched_des, NOSCHED_DES)
#undef _ENTRY
};

const struct cn30xxpow_dump_ops_entry cn30xxpow_dump_ops_queue_entries[] = {
#define	_ENTRY(x, y)	_ENTRY_COMMON(queue, POW_IDXPTR_LOAD_RESULT_QUEUE, x, y)
	_ENTRY(remote_head, REMOTE_HEAD),
	_ENTRY(remote_tail, REMOTE_TAIL)
#undef _ENTRY
};

void
cn30xxpow_dump_ops(void)
{
	int i;

	/* XXX */
	for (i = 0; i < 2/* XXX */; i++)
		cn30xxpow_dump_ops_coreid(i);

	/* XXX */
	cn30xxpow_dump_ops_index(0);

	for (i = 0; i < 8; i++)
		cn30xxpow_dump_ops_qos(i);

	for (i = 0; i < 16; i++)
		cn30xxpow_dump_ops_grp(i);

	for (i = 0; i < 16; i++)
		cn30xxpow_dump_ops_queue(i);
}

void
cn30xxpow_dump_ops_coreid(int coreid)
{
	cn30xxpow_dump_ops_common(cn30xxpow_dump_ops_coreid_entries,
	    nitems(cn30xxpow_dump_ops_coreid_entries), "coreid", coreid);
}

void
cn30xxpow_dump_ops_index(int index)
{
	cn30xxpow_dump_ops_common(cn30xxpow_dump_ops_index_entries,
	    nitems(cn30xxpow_dump_ops_index_entries), "index", index);
}

void
cn30xxpow_dump_ops_qos(int qos)
{
	cn30xxpow_dump_ops_common(cn30xxpow_dump_ops_qos_entries,
	    nitems(cn30xxpow_dump_ops_qos_entries), "qos", qos);
}

void
cn30xxpow_dump_ops_grp(int grp)
{
	cn30xxpow_dump_ops_common(cn30xxpow_dump_ops_grp_entries,
	    nitems(cn30xxpow_dump_ops_grp_entries), "grp", grp);
}

void
cn30xxpow_dump_ops_queue(int queue)
{
	cn30xxpow_dump_ops_common(cn30xxpow_dump_ops_queue_entries,
	    nitems(cn30xxpow_dump_ops_queue_entries), "queue", queue);
}

void
cn30xxpow_dump_ops_common(const struct cn30xxpow_dump_ops_entry *entries,
    size_t nentries, const char *by_what, int arg)
{
	const struct cn30xxpow_dump_ops_entry *entry;
	uint64_t tmp;
	int i;

	printf("%s=%d\n", by_what, arg);
	for (i = 0; i < (int)nentries; i++) {
		entry = &entries[i];
		tmp = (*entry->func)(arg);
		printf("\t%-24s: %16llx\n", entry->name, tmp);
	}
}

#endif

/* -------------------------------------------------------------------------- */

/* ---- test */

#ifdef OCTEON_POW_TEST
/*
 * Standalone test entries; meant to be called from ddb.
 */

void		cn30xxpow_test(void);
void		cn30xxpow_test_dump_wqe(paddr_t);

void		cn30xxpow_test_1(void);

struct test_wqe {
	uint64_t word0;
	uint64_t word1;
	uint64_t word2;
	uint64_t word3;
} __packed;
struct test_wqe test_wqe;

void
cn30xxpow_test(void)
{
	cn30xxpow_test_1();
}

void
cn30xxpow_test_1(void)
{
	struct test_wqe *wqe = &test_wqe;
	int qos, grp, queue, tt;
	uint32_t tag;
	paddr_t ptr;

	qos = 7;			/* XXX */
	grp = queue = 15;		/* XXX */
	tt = POW_TAG_TYPE_ORDERED;	/* XXX */
	tag = UINT32_C(0x01234567);	/* XXX */

	/* => make sure that the queue is empty */

	cn30xxpow_dump_ops_qos(qos);
	cn30xxpow_dump_ops_grp(grp);
	printf("\n");

	/*
	 * Initialize WQE.
	 *
	 * word0:next is used by hardware.
	 *
	 * word1:qos, word1:grp, word1:tt, word1:tag must match with arguments
	 * of the following ADDWQ transaction.
	 */

	(void)memset(wqe, 0, sizeof(*wqe));
	wqe->word0 =
	    __BITS64_SET(POW_WQE_WORD0_NEXT, 0);
	wqe->word1 =
	    __BITS64_SET(POW_WQE_WORD1_QOS, qos) |
	    __BITS64_SET(POW_WQE_WORD1_GRP, grp) |
	    __BITS64_SET(POW_WQE_WORD1_TT, tt) |
	    __BITS64_SET(POW_WQE_WORD1_TAG, tag);

	printf("calling ADDWQ\n");
	cn30xxpow_ops_addwq(MIPS_KSEG0_TO_PHYS(wqe), qos, grp, tt, tag);

	cn30xxpow_dump_ops_qos(qos);
	cn30xxpow_dump_ops_grp(grp);
	printf("\n");

	/* => make sure that a WQE is added to the queue */

	printf("calling GET_WORK_LOAD\n");
	ptr = cn30xxpow_ops_get_work_load(0);

	cn30xxpow_dump_ops_qos(qos);
	cn30xxpow_dump_ops_grp(grp);
	printf("\n");

	cn30xxpow_test_dump_wqe(ptr);

	/* => make sure that the WQE is in-flight (and scheduled) */

	printf("calling SWTAG(NULL)\n");
	cn30xxpow_ops_swtag(POW_TAG_TYPE_NULL, tag);

	cn30xxpow_dump_ops_qos(qos);
	cn30xxpow_dump_ops_grp(grp);
	printf("\n");

	/* => make sure that the WQE is un-scheduled (completed) */
}

void
cn30xxpow_test_dump_wqe(paddr_t ptr)
{
	uint64_t word0, word1;

	printf("wqe\n");

	word0 = *(uint64_t *)PHYS_TO_XKPHYS(ptr, CCA_CACHED);
	printf("\t%-24s: %16llx\n", "word0", word0);

	word1 = *(uint64_t *)PHYS_TO_XKPHYS(ptr + 8, CCA_CACHED);
	printf("\t%-24s: %16llx\n", "word1", word1);
}
#endif


code:
/*
 * THIS FILE IS AUTOMATICALLY GENERATED
 * DONT EDIT THIS FILE
 */

/*	$OpenBSD: cn30xxpowreg.h,v 1.2 2014/08/11 18:29:56 miod Exp $	*/

/*
 * Copyright (c) 2007 Internet Initiative Japan, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Cavium Networks OCTEON CN30XX Hardware Reference Manual
 * CN30XX-HM-1.0
 * 5.12 POW Registers
 */

#ifndef _CN30XXPOWREG_H_
#define _CN30XXPOWREG_H_

/* ---- register addresses */

#define	POW_PP_GRP_MSK0				0x0001670000000000ULL
#define	POW_PP_GRP_MSK1				0x0001670000000008ULL
#define	POW_WQ_INT_THR0				0x0001670000000080ULL
#define	POW_WQ_INT_THR1				0x0001670000000088ULL
#define	POW_WQ_INT_THR2				0x0001670000000090ULL
#define	POW_WQ_INT_THR3				0x0001670000000098ULL
#define	POW_WQ_INT_THR4				0x00016700000000a0ULL
#define	POW_WQ_INT_THR5				0x00016700000000a8ULL
#define	POW_WQ_INT_THR6				0x00016700000000b0ULL
#define	POW_WQ_INT_THR7				0x00016700000000b8ULL
#define	POW_WQ_INT_THR8				0x00016700000000c0ULL
#define	POW_WQ_INT_THR9				0x00016700000000c8ULL
#define	POW_WQ_INT_THR10			0x00016700000000d0ULL
#define	POW_WQ_INT_THR11			0x00016700000000d8ULL
#define	POW_WQ_INT_THR12			0x00016700000000e0ULL
#define	POW_WQ_INT_THR13			0x00016700000000e8ULL
#define	POW_WQ_INT_THR14			0x00016700000000f0ULL
#define	POW_WQ_INT_THR15			0x00016700000000f8ULL
#define	POW_WQ_INT_CNT0				0x0001670000000100ULL
#define	POW_WQ_INT_CNT1				0x0001670000000108ULL
#define	POW_WQ_INT_CNT2				0x0001670000000110ULL
#define	POW_WQ_INT_CNT3				0x0001670000000118ULL
#define	POW_WQ_INT_CNT4				0x0001670000000120ULL
#define	POW_WQ_INT_CNT5				0x0001670000000128ULL
#define	POW_WQ_INT_CNT6				0x0001670000000130ULL
#define	POW_WQ_INT_CNT7				0x0001670000000138ULL
#define	POW_WQ_INT_CNT8				0x0001670000000140ULL
#define	POW_WQ_INT_CNT9				0x0001670000000148ULL
#define	POW_WQ_INT_CNT10			0x0001670000000150ULL
#define	POW_WQ_INT_CNT11			0x0001670000000158ULL
#define	POW_WQ_INT_CNT12			0x0001670000000160ULL
#define	POW_WQ_INT_CNT13			0x0001670000000168ULL
#define	POW_WQ_INT_CNT14			0x0001670000000170ULL
#define	POW_WQ_INT_CNT15			0x0001670000000178ULL
#define	POW_QOS_THR0				0x0001670000000180ULL
#define	POW_QOS_THR1				0x0001670000000188ULL
#define	POW_QOS_THR2				0x0001670000000190ULL
#define	POW_QOS_THR3				0x0001670000000198ULL
#define	POW_QOS_THR4				0x00016700000001a0ULL
#define	POW_QOS_THR5				0x00016700000001a8ULL
#define	POW_QOS_THR6				0x00016700000001b0ULL
#define	POW_QOS_THR7				0x00016700000001b8ULL
#define	POW_QOS_RND0				0x00016700000001c0ULL
#define	POW_QOS_RND1				0x00016700000001c8ULL
#define	POW_QOS_RND2				0x00016700000001d0ULL
#define	POW_QOS_RND3				0x00016700000001d8ULL
#define	POW_QOS_RND4				0x00016700000001e0ULL
#define	POW_QOS_RND5				0x00016700000001e8ULL
#define	POW_QOS_RND6				0x00016700000001f0ULL
#define	POW_QOS_RND7				0x00016700000001f8ULL
#define	POW_WQ_INT				0x0001670000000200ULL
#define	POW_WQ_INT_PC				0x0001670000000208ULL
#define	POW_NW_TIM				0x0001670000000210ULL
#define	POW_ECC_ERR				0x0001670000000218ULL
#define	POW_NOS_CNT				0x0001670000000220ULL
#define	POW_WS_PC0				0x0001670000000280ULL
#define	POW_WS_PC1				0x0001670000000288ULL
#define	POW_WS_PC2				0x0001670000000290ULL
#define	POW_WS_PC3				0x0001670000000298ULL
#define	POW_WS_PC4				0x00016700000002a0ULL
#define	POW_WS_PC5				0x00016700000002a8ULL
#define	POW_WS_PC6				0x00016700000002b0ULL
#define	POW_WS_PC7				0x00016700000002b8ULL
#define	POW_WS_PC8				0x00016700000002c0ULL
#define	POW_WS_PC9				0x00016700000002c8ULL
#define	POW_WS_PC10				0x00016700000002d0ULL
#define	POW_WS_PC11				0x00016700000002d8ULL
#define	POW_WS_PC12				0x00016700000002e0ULL
#define	POW_WS_PC13				0x00016700000002e8ULL
#define	POW_WS_PC14				0x00016700000002f0ULL
#define	POW_WS_PC15				0x00016700000002f8ULL
#define	POW_WA_PC0				0x0001670000000300ULL
#define	POW_WA_PC1				0x0001670000000308ULL
#define	POW_WA_PC2				0x0001670000000310ULL
#define	POW_WA_PC3				0x0001670000000318ULL
#define	POW_WA_PC4				0x0001670000000320ULL
#define	POW_WA_PC5				0x0001670000000328ULL
#define	POW_WA_PC6				0x0001670000000330ULL
#define	POW_WA_PC7				0x0001670000000338ULL
#define	POW_IQ_CNT0				0x0001670000000340ULL
#define	POW_IQ_CNT1				0x0001670000000348ULL
#define	POW_IQ_CNT2				0x0001670000000350ULL
#define	POW_IQ_CNT3				0x0001670000000358ULL
#define	POW_IQ_CNT4				0x0001670000000360ULL
#define	POW_IQ_CNT5				0x0001670000000368ULL
#define	POW_IQ_CNT6				0x0001670000000370ULL
#define	POW_IQ_CNT7				0x0001670000000378ULL
#define	POW_WA_COM_PC				0x0001670000000380ULL
#define	POW_IQ_COM_CNT				0x0001670000000388ULL
#define	POW_TS_PC				0x0001670000000390ULL
#define	POW_DS_PC				0x0001670000000398ULL
#define	POW_BIST_STAT				0x00016700000003f8ULL

#define POW_BASE				0x0001670000000000ULL
#define POW_SIZE				0x400ULL

#define	POW_PP_GRP_MSK0_OFFSET			0x0ULL
#define	POW_PP_GRP_MSK1_OFFSET			0x8ULL
#define	POW_WQ_INT_THR0_OFFSET			0x80ULL
#define	POW_WQ_INT_THR1_OFFSET			0x88ULL
#define	POW_WQ_INT_THR2_OFFSET			0x90ULL
#define	POW_WQ_INT_THR3_OFFSET			0x98ULL
#define	POW_WQ_INT_THR4_OFFSET			0xa0ULL
#define	POW_WQ_INT_THR5_OFFSET			0xa8ULL
#define	POW_WQ_INT_THR6_OFFSET			0xb0ULL
#define	POW_WQ_INT_THR7_OFFSET			0xb8ULL
#define	POW_WQ_INT_THR8_OFFSET			0xc0ULL
#define	POW_WQ_INT_THR9_OFFSET			0xc8ULL
#define	POW_WQ_INT_THR10_OFFSET			0xd0ULL
#define	POW_WQ_INT_THR11_OFFSET			0xd8ULL
#define	POW_WQ_INT_THR12_OFFSET			0xe0ULL
#define	POW_WQ_INT_THR13_OFFSET			0xe8ULL
#define	POW_WQ_INT_THR14_OFFSET			0xf0ULL
#define	POW_WQ_INT_THR15_OFFSET			0xf8ULL
#define	POW_WQ_INT_CNT0_OFFSET			0x100ULL
#define	POW_WQ_INT_CNT1_OFFSET			0x108ULL
#define	POW_WQ_INT_CNT2_OFFSET			0x110ULL
#define	POW_WQ_INT_CNT3_OFFSET			0x118ULL
#define	POW_WQ_INT_CNT4_OFFSET			0x120ULL
#define	POW_WQ_INT_CNT5_OFFSET			0x128ULL
#define	POW_WQ_INT_CNT6_OFFSET			0x130ULL
#define	POW_WQ_INT_CNT7_OFFSET			0x138ULL
#define	POW_WQ_INT_CNT8_OFFSET			0x140ULL
#define	POW_WQ_INT_CNT9_OFFSET			0x148ULL
#define	POW_WQ_INT_CNT10_OFFSET			0x150ULL
#define	POW_WQ_INT_CNT11_OFFSET			0x158ULL
#define	POW_WQ_INT_CNT12_OFFSET			0x160ULL
#define	POW_WQ_INT_CNT13_OFFSET			0x168ULL
#define	POW_WQ_INT_CNT14_OFFSET			0x170ULL
#define	POW_WQ_INT_CNT15_OFFSET			0x178ULL
#define	POW_QOS_THR0_OFFSET			0x180ULL
#define	POW_QOS_THR1_OFFSET			0x188ULL
#define	POW_QOS_THR2_OFFSET			0x190ULL
#define	POW_QOS_THR3_OFFSET			0x198ULL
#define	POW_QOS_THR4_OFFSET			0x1a0ULL
#define	POW_QOS_THR5_OFFSET			0x1a8ULL
#define	POW_QOS_THR6_OFFSET			0x1b0ULL
#define	POW_QOS_THR7_OFFSET			0x1b8ULL
#define	POW_QOS_RND0_OFFSET			0x1c0ULL
#define	POW_QOS_RND1_OFFSET			0x1c8ULL
#define	POW_QOS_RND2_OFFSET			0x1d0ULL
#define	POW_QOS_RND3_OFFSET			0x1d8ULL
#define	POW_QOS_RND4_OFFSET			0x1e0ULL
#define	POW_QOS_RND5_OFFSET			0x1e8ULL
#define	POW_QOS_RND6_OFFSET			0x1f0ULL
#define	POW_QOS_RND7_OFFSET			0x1f8ULL
#define	POW_WQ_INT_OFFSET			0x200ULL
#define	POW_WQ_INT_PC_OFFSET			0x208ULL
#define	POW_NW_TIM_OFFSET			0x210ULL
#define	POW_ECC_ERR_OFFSET			0x218ULL
#define	POW_NOS_CNT_OFFSET			0x220ULL
#define	POW_WS_PC0_OFFSET			0x280ULL
#define	POW_WS_PC1_OFFSET			0x288ULL
#define	POW_WS_PC2_OFFSET			0x290ULL
#define	POW_WS_PC3_OFFSET			0x298ULL
#define	POW_WS_PC4_OFFSET			0x2a0ULL
#define	POW_WS_PC5_OFFSET			0x2a8ULL
#define	POW_WS_PC6_OFFSET			0x2b0ULL
#define	POW_WS_PC7_OFFSET			0x2b8ULL
#define	POW_WS_PC8_OFFSET			0x2c0ULL
#define	POW_WS_PC9_OFFSET			0x2c8ULL
#define	POW_WS_PC10_OFFSET			0x2d0ULL
#define	POW_WS_PC11_OFFSET			0x2d8ULL
#define	POW_WS_PC12_OFFSET			0x2e0ULL
#define	POW_WS_PC13_OFFSET			0x2e8ULL
#define	POW_WS_PC14_OFFSET			0x2f0ULL
#define	POW_WS_PC15_OFFSET			0x2f8ULL
#define	POW_WA_PC0_OFFSET			0x300ULL
#define	POW_WA_PC1_OFFSET			0x308ULL
#define	POW_WA_PC2_OFFSET			0x310ULL
#define	POW_WA_PC3_OFFSET			0x318ULL
#define	POW_WA_PC4_OFFSET			0x320ULL
#define	POW_WA_PC5_OFFSET			0x328ULL
#define	POW_WA_PC6_OFFSET			0x330ULL
#define	POW_WA_PC7_OFFSET			0x338ULL
#define	POW_IQ_CNT0_OFFSET			0x340ULL
#define	POW_IQ_CNT1_OFFSET			0x348ULL
#define	POW_IQ_CNT2_OFFSET			0x350ULL
#define	POW_IQ_CNT3_OFFSET			0x358ULL
#define	POW_IQ_CNT4_OFFSET			0x360ULL
#define	POW_IQ_CNT5_OFFSET			0x368ULL
#define	POW_IQ_CNT6_OFFSET			0x370ULL
#define	POW_IQ_CNT7_OFFSET			0x378ULL
#define	POW_WA_COM_PC_OFFSET			0x380ULL
#define	POW_IQ_COM_CNT_OFFSET			0x388ULL
#define	POW_TS_PC_OFFSET			0x390ULL
#define	POW_DS_PC_OFFSET			0x398ULL
#define	POW_BIST_STAT_OFFSET			0x3f8ULL

/* ---- register bits */

#define	POW_PP_GRP_MSKX_XXX_63_16		0xffffffffffff0000ULL
#define	POW_PP_GRP_MSKX_GRP_MSK			0x000000000000ffffULL
#define	 POW_PP_GRP_MSKX_GRP_MSK_SHIFT		0

#define	POW_WQ_INT_THRX_XXX_63_29		0xffffffffe0000000ULL
#define	POW_WQ_INT_THRX_TC_EN			0x0000000010000000ULL
#define	POW_WQ_INT_THRX_TC_THR			0x000000000f000000ULL
#define	 POW_WQ_INT_THRX_TC_THR_SHIFT		24
#define	POW_WQ_INT_THRX_XXX_23_18		0x0000000000fc0000ULL
#define	POW_WQ_INT_THRX_DS_THR			0x000000000003f000ULL
#define	 POW_WQ_INT_THRX_DS_THR_SHIFT		12
#define	POW_WQ_INT_THRX_XXX_11_6		0x0000000000000fc0ULL
#define	POW_WQ_INT_THRX_IQ_THR			0x000000000000003fULL
#define	 POW_WQ_INT_THRX_IQ_THR_SHIFT		0

#define	POW_WQ_INT_CNTX_XXX_63_28		0xfffffffff0000000ULL
#define	POW_WQ_INT_CNTX_TC_CNT			0x000000000f000000ULL
#define	 POW_WQ_INT_CNTX_TC_CNT_SHIFT		24
#define	POW_WQ_INT_CNTX_XXX_23_18		0x0000000000fc0000ULL
#define	POW_WQ_INT_CNTX_DS_CNT			0x000000000003f000ULL
#define	 POW_WQ_INT_CNTX_DS_CNT_SHIFT		12
#define	POW_WQ_INT_CNTX_XXX_11_6		0x0000000000000fc0ULL
#define	POW_WQ_INT_CNTX_IQ_CNT			0x000000000000003fULL
#define	 POW_WQ_INT_CNTX_IQ_CNT_SHIFT		0

#define	POW_QOS_THRX_XXX_63_55			0xff80000000000000ULL
#define	POW_QOS_THRX_DES_CNT			0x007f000000000000ULL
#define	 POW_QOS_THRX_DES_CNT_SHIFT		48
#define	POW_QOS_THRX_XXX_47_43			0x0000f80000000000ULL
#define	POW_QOS_THRX_BUF_CNT			0x000007f000000000ULL
#define	 POW_QOS_THRX_BUF_CNT_SHIFT		36
#define	POW_QOS_THRX_XXX_35_31			0x0000000f80000000ULL
#define	POW_QOS_THRX_FREE_CNT			0x000000007f000000ULL
#define	 POW_QOS_THRX_FREE_CNT_SHIFT		24
#define	POW_QOS_THRX_XXX_23_18			0x0000000000fc0000ULL
#define	POW_QOS_THRX_MAX_THR			0x000000000003f000ULL
#define	 POW_QOS_THRX_MAX_THR_SHIFT		12
#define	POW_QOS_THRX_XXX_11_6			0x0000000000000fc0ULL
#define	POW_QOS_THRX_MIN_THR			0x000000000000003fULL
#define	 POW_QOS_THRX_MIN_THR_SHIFT		0

#define	POW_QOS_RNDX_XXX_63_32			0xffffffff00000000ULL
#define	POW_QOS_RNDX_RND_P3			0x00000000ff000000ULL
#define	 POW_QOS_RNDX_RND_P3_SHIFT		24
#define	POW_QOS_RNDX_RND_P2			0x0000000000ff0000ULL
#define	 POW_QOS_RNDX_RND_P2_SHIFT		16
#define	POW_QOS_RNDX_RND_P1			0x000000000000ff00ULL
#define	 POW_QOS_RNDX_RND_P1_SHIFT		8
#define	POW_QOS_RNDX_RND			0x00000000000000ffULL
#define	 POW_QOS_RNDX_RND_SHIFT			0

#define	POW_WQ_INT_XXX_63_32			0xffffffff00000000ULL
#define	POW_WQ_INT_IQ_DIS			0x00000000ffff0000ULL
#define	 POW_WQ_INT_IQ_DIS_SHIFT		16
#define	POW_WQ_INT_WQ_INT			0x000000000000ffffULL
#define	 POW_WQ_INT_WQ_INT_SHIFT		0

#define	POW_WQ_INT_PC_XXX_63_60			0xf000000000000000ULL
#define	POW_WQ_INT_PC_PC			0x0fffffff00000000ULL
#define	 POW_WQ_INT_PC_PC_SHIFT			32
#define	POW_WQ_INT_PC_XXX_31_28			0x00000000f0000000ULL
#define	POW_WQ_INT_PC_PC_THR			0x000000000fffff00ULL
#define	 POW_WQ_INT_PC_PC_THR_SHIFT		8
#define	POW_WQ_INT_PC_XXX_7_0			0x00000000000000ffULL

#define	POW_NW_TIM_XXX_63_10			0xfffffffffffffc00ULL
#define	POW_NW_TIM_NW_TIM			0x00000000000003ffULL
#define	 POW_NW_TIM_NW_TIM_SHIFT		0

#define	POW_ECC_ERR_XXX_63_45			0xffffe00000000000ULL
#define	POW_ECC_ERR_IOP_IE			0x00001fff00000000ULL
#define	 POW_ECC_ERR_IOP_IE_SHIFT		32
#define	POW_ECC_ERR_XXX_31_29			0x00000000e0000000ULL
#define	POW_ECC_ERR_IOP				0x000000001fff0000ULL
#define	 POW_ECC_ERR_IOP_SHIFT			16
#define	  POW_ECC_ERR_IOP_CSRPEND		(28) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_DBGPEND		(27) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_ADDWORK		(26) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_ILLOP			(25) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_PEND24		(24) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_PEND23		(23) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_PEND22		(22) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_PEND21		(21) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_TAGNULL		(20) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_TAGNULLNULL		(19) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_ORDATOM		(18) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_NULL			(17) << POW_ECC_ERR_IOP_SHIFTULL
#define	  POW_ECC_ERR_IOP_NULLNULL		(16) << POW_ECC_ERR_IOP_SHIFTULL
#define	POW_ECC_ERR_XXX_15_14			0x000000000000c000ULL
#define	POW_ECC_ERR_RPE_IE			0x0000000000002000ULL
#define	POW_ECC_ERR_RPE				0x0000000000001000ULL
#define	POW_ECC_ERR_XXX_11_9			0x0000000000000e00ULL
#define	POW_ECC_ERR_SYN				0x00000000000001f0ULL
#define	 POW_ECC_ERR_SYN_SHIFT			4
#define	POW_ECC_ERR_DBE_IE			0x0000000000000008ULL
#define	POW_ECC_ERR_SBE_IE			0x0000000000000004ULL
#define	POW_ECC_ERR_DBE				0x0000000000000002ULL
#define	POW_ECC_ERR_SBE				0x0000000000000001ULL

#define	POW_NOS_CNT_XXX_63_7			0xffffffffffffff80ULL
#define	POW_NOS_CNT_NOS_CNT			0x000000000000007fULL
#define	 POW_NOS_CNT_NOS_CNT_SHIFT		0

#define	POW_WS_PC0_XXX_63_32			0xffffffff00000000ULL
#define	POW_WS_PC0_WS_PC			0x00000000ffffffffULL
#define	 POW_WS_PC0_WS_PC_SHIFT			0

#define	POW_WA_PC0_XXX_63_32			0xffffffff00000000ULL
#define	POW_WA_PC0_WA_PC			0x00000000ffffffffULL
#define	 POW_WA_PC0_WA_PC_SHIFT			0

#define	POW_IQ_CNT0_XXX_63_32			0xffffffff00000000ULL
#define	POW_IQ_CNT0_IQ_CNT			0x00000000ffffffffULL
#define	 POW_IQ_CNT0_IQ_CNT_SHIFT		0

#define	POW_WA_COM_PC_XXX_63_32			0xffffffff00000000ULL
#define	POW_WA_COM_PC_WA_PC			0x00000000ffffffffULL
#define	 POW_WA_COM_PC_WA_PC_SHIFT		0

#define	POW_WQ_COM_CNT_XXX_63_32		0xffffffff00000000ULL
#define	POW_WQ_COM_CNT_IQ_CNT			0x00000000ffffffffULL
#define	 POW_WQ_COM_CNT_IQ_CNT_SHIFT		0

#define	POW_TS_PC_XXX_63_32			0xffffffff00000000ULL
#define	POW_TS_PC_TS_PC				0x00000000ffffffffULL
#define	 POW_TS_PC_TS_PC_SHIFT			0

#define	POW_DS_PC_XXX_63_32			0xffffffff00000000ULL
#define	POW_DS_PC_DS_PC				0x00000000ffffffffULL
#define	 POW_DS_PC_DS_PC_SHIFT			0

#define	POW_BIST_STAT_XXX_63_7			0xfffffffffffe0000ULL
#define	POW_BIST_STAT_PP			0x0000000000010000ULL
#define	POW_BIST_STAT_XXX_15_9			0x000000000000fe00ULL
#define	POW_BIST_STAT_CAM			0x0000000000000100ULL
#define	POW_BIST_STAT_NBT1			0x0000000000000080ULL
#define	POW_BIST_STAT_NBT0			0x0000000000000040ULL
#define	POW_BIST_STAT_IDX			0x0000000000000020ULL
#define	POW_BIST_STAT_FIDX			0x0000000000000010ULL
#define	POW_BIST_STAT_NBR1			0x0000000000000008ULL
#define	POW_BIST_STAT_NBR0			0x0000000000000004ULL
#define	POW_BIST_STAT_PEND			0x0000000000000002ULL
#define	POW_BIST_STAT_ADR			0x0000000000000001ULL

/* ---- pow operations */

/* pow operations base */
#define POW_OPERATION_BASE_IO_BIT		0x0001000000000000ULL
#define POW_OPERATION_BASE_MAJOR_DID		0x0000f80000000000ULL
#define POW_OPERATION_BASE_SUB_DID		0x0000070000000000ULL
#define	POW_OPERATION_BASE_IO_BIT_SHIFT	48
#define	POW_OPERATION_BASE_MAJOR_DID_SHIFT	43
#define	POW_OPERATION_BASE_SUB_DID_SHIFT	40

/* get work load  (subid = 0) */
#define POW_GET_WORK_LOAD_WAIT			0x0000000000000008ULL
#define POW_GET_WORK_LOAD_2_0			0x0000000000000007ULL
#define	POW_GET_WORK_LOAD_WAIT_SHIFT	3
#define	POW_GET_WORK_LOAD_2_0_SHIFT	0

#define POW_GET_WORK_LOAD_RESULT_NO_WORK	0x8000000000000000ULL
#define POW_GET_WORK_LOAD_RESULT_62_40		0x7fffff0000000000ULL
#define POW_GET_WORK_LOAD_RESULT_ADDR		0x000000ffffffffffULL

/* pow status load (subid = 1) */
#define POW_STATUS_LOAD_COREID			0x00000000000003c0ULL
#define POW_STATUS_LOAD_GET_REV			0x0000000000000020ULL
#define POW_STATUS_LOAD_GET_CUR			0x0000000000000010ULL
#define POW_STATUS_LOAD_GET_WQP			0x0000000000000008ULL
#define POW_STATUS_LOAD_GET_2_0			0x0000000000000007ULL
#define	POW_STATUS_LOAD_COREID_SHIFT	6
#define	POW_STATUS_LOAD_GET_REV_SHIFT	5
#define	POW_STATUS_LOAD_GET_CUR_SHIFT	4
#define	POW_STATUS_LOAD_GET_WQP_SHIFT	3
#define	POW_STATUS_LOAD_GET_2_0_SHIFT	0

/* get_cur = 0 and get_wqp = 0 ("pend_tag") */
#define POW_STATUS_LOAD_RESULT_PEND_TAG_XXX_63_62		0xc000000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_SWITCH		0x2000000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_SWITCH_FULL	0x1000000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_SWITCH_NULL	0x0800000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_DESCHED		0x0400000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_DESCHED_SWITCH	0x0200000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_NOSCHED		0x0100000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_NEW_WORK		0x0080000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_NEW_WORK_WAIT	0x0040000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_NULL_RD		0x0020000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_NOSCHED_CLR	0x0010000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_XXX_51		0x0008000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_INDEX		0x0007ff0000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_GRP		0x000000f000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_XXX_35_34		0x0000000c00000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_TYPE		0x0000000300000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_TAG_PEND_TAG		0x00000000ffffffffULL

/* get_cur = 0 and get_wqp = 1 ("pend_wqp") */
#define POW_STATUS_LOAD_RESULT_PEND_WQP_XXX_63_62		0xc000000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_SWITCH		0x2000000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_SWITCH_FULL	0x1000000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_SWITCH_NULL	0x0800000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_DESCHED		0x0400000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_DESCHED_SWITCH	0x0200000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_NOSCHED		0x0100000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_NEW_WORK		0x0080000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_NEW_WORK_WAIT	0x0040000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_NULL_RD		0x0020000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_NOSCHED_CLR	0x0010000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_XXX_51		0x0008000000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_INDEX		0x0007ff0000000000ULL
#define POW_STATUS_LOAD_RESULT_PEND_WQP_PEND_WQP		0x0000000fffffffffULL

/* get_cur = 1 and get_wqp = 0 and get_rev = 0 ("cur_tag_next") */
#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_XXX_63_62		0xc000000000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_LINK_INDEX		0x3ff8000000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_INDEX		0x0007ff0000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_GRP			0x000000f000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_HEAD		0x0000000800000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_TAIL		0x0000000400000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_TAG_TYPE		0x0000000300000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_NEXT_TAG			0x00000000ffffffffULL

/* get_cur = 1 and get_wqp = 0 and get_rev = 1 ("cur_tag_prev") */
#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_XXX_63_62		0xc000000000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_REVLINK_INDEX	0x3ff8000000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_INDEX		0x0007ff0000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_GRP			0x000000f000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_HEAD		0x0000000800000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_TAIL		0x0000000400000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_TAG_TYPE		0x0000000300000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_TAG_PREV_TAG			0x00000000ffffffffULL

/* get_cur = 1 and get_wqp = 1 and get_rev = 0 ("cur_wqp_next") */
#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_XXX_63_62		0xc000000000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_LINK_INDEX		0x3ff8000000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_INDEX		0x0007ff0000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_GRP			0x000000f000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_WQP_NEXT_WQP			0x0000000fffffffffULL

/* get_cur = 1 and get_wqp = 1 and get_rev = 1 ("cur_wqp_prev") */
#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_XXX_63_62		0xc000000000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_REVLINK_INDEX	0x3ff8000000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_INDEX		0x0007ff0000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_GRP			0x000000f000000000ULL
#define POW_STATUS_LOAD_RESULT_CUR_WQP_PREV_WQP			0x0000000fffffffffULL

/* pow memory load (subid = 2) */
#define POW_MEMORY_LOAD_INDEX		0x000000000000ffe0ULL
#define POW_MEMORY_LOAD_GET_DES		0x0000000000000010ULL
#define POW_MEMORY_LOAD_GET_WQP		0x0000000000000008ULL
#define POW_MEMORY_LOAD_2_0		0x0000000000000007ULL
#define	POW_MEMORY_LOAD_GET_DES_SHIFT	4
#define	POW_MEMORY_LOAD_INDEX_SHIFT	5
#define	POW_MEMORY_LOAD_2_0_SHIFT	0
#define	POW_MEMORY_LOAD_GET_WQP_SHIFT	3

/* get_des = 0 and get_wqp = 0 ("tag") */
#define POW_MEMORY_LOAD_RESULT_TAG_XXX_63_51			0xfff8000000000000ULL
#define POW_MEMORY_LOAD_RESULT_TAG_NEXT_INDEX			0x0007ff0000000000ULL
#define POW_MEMORY_LOAD_RESULT_TAG_GRP				0x000000f000000000ULL
#define POW_MEMORY_LOAD_RESULT_TAG_XXX_35			0x0000000800000000ULL
#define POW_MEMORY_LOAD_RESULT_TAG_TAIL				0x0000000400000000ULL
#define POW_MEMORY_LOAD_RESULT_TAG_TAG_TYPE			0x0000000300000000ULL
#define POW_MEMORY_LOAD_RESULT_TAG_TAG				0x00000000ffffffffULL

/* get_des = 0 and get_wqp = 1 ("wqp") */
#define POW_MEMORY_LOAD_RESULT_WQP_XXX_63_51			0xfff8000000000000ULL
#define POW_MEMORY_LOAD_RESULT_WQP_NEXT_INDEX			0x0007ff0000000000ULL
#define POW_MEMORY_LOAD_RESULT_WQP_GRP				0x000000f000000000ULL
#define POW_MEMORY_LOAD_RESULT_WQP_WQP				0x0000000fffffffffULL

/* get_des = 1 ("desched") */
#define POW_MEMORY_LOAD_RESULT_DESCHED_XXX_63_51		0xfff8000000000000ULL
#define POW_MEMORY_LOAD_RESULT_DESCHED_FWD_INDEX		0x0007ff0000000000ULL
#define POW_MEMORY_LOAD_RESULT_DESCHED_GRP			0x000000f000000000ULL
#define POW_MEMORY_LOAD_RESULT_DESCHED_NOSCHED			0x0000000800000000ULL
#define POW_MEMORY_LOAD_RESULT_DESCHED_PEND_SWITCH		0x0000000400000000ULL
#define POW_MEMORY_LOAD_RESULT_DESCHED_PEND_TYPE		0x0000000300000000ULL
#define POW_MEMORY_LOAD_RESULT_DESCHED_PEND_TAG			0x00000000ffffffffULL

/* pow index/pointer load (subid = 3) */
#define POW_IDXPTR_LOAD_QOSGRP			0x00000000000001e0ULL
#define POW_IDXPTR_LOAD_GET_DES_GET_TAIL	0x0000000000000010ULL
#define POW_IDXPTR_LOAD_GET_RMT			0x0000000000000008ULL
#define POW_IDXPTR_LOAD_2_0			0x0000000000000007ULL
#define	POW_IDXPTR_LOAD_GET_DES_GET_TAIL_SHIFT	4
#define	POW_IDXPTR_LOAD_QOSGRP_SHIFT	5
#define	POW_IDXPTR_LOAD_2_0_SHIFT	0
#define	POW_IDXPTR_LOAD_GET_RMT_SHIFT	3

/* get_rmt = 0 and get_des_get_tail = 0 ("qos") */
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_XXX_63_52		0xfff0000000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_FREE_VAL		0x0008000000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_FREE_ONE		0x0004000000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_XXX_49		0x0002000000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_FREE_HEAD		0x0001ffc000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_XXX_37		0x0000002000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_FREE_TAIL		0x0000001ffc000000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_LOC_VAL		0x0000000002000000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_LOC_ONE		0x0000000001000000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_XXX_23		0x0000000000800000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_LOC_HEAD		0x00000000007ff000ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_XXX_11		0x0000000000000800ULL
#define POW_IDXPTR_LOAD_RESULT_QOS_FREE_LOC_LOC_TAIL		0x00000000000007ffULL

/* get_rmt = 0 and get_des_get_tail = 1 ("desched") */
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_XXX_63_52	0xfff0000000000000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_NOSCHED_VAL	0x0008000000000000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_NOSCHED_ONE	0x0004000000000000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_XXX_49		0x0002000000000000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_NOSCHED_HEAD	0x0001ffc000000000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_XXX_37		0x0000002000000000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_NOSCHED_TAIL	0x0000001ffc000000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_DES_VAL		0x0000000002000000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_DES_ONE		0x0000000001000000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_XXX_23		0x0000000000800000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_DES_HEAD		0x00000000007ff000ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_XXX_11		0x0000000000000800ULL
#define POW_IDXPTR_LOAD_RESULT_GRP_NOSCHED_DES_DES_TAIL		0x00000000000007ffULL

/* get_rmt = 1 and get_des_get_tail = 0 ("remote_head") */
#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_XXX_63_39	0xffffff8000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_RMT_IS_HEAD	0x0000004000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_RMT_VAL	0x0000002000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_RMT_ONE	0x0000001000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_HEAD_RMT_HEAD	0x0000000fffffffffULL

/* get_rmt = 1 and get_des_get_tail = 1 ("remote_tail") */
#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_XXX_63_39	0xffffff8000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_RMT_IS_HEAD	0x0000004000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_RMT_VAL	0x0000002000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_RMT_ONE	0x0000001000000000ULL
#define POW_IDXPTR_LOAD_RESULT_QUEUE_REMOTE_TAIL_RMT_TAIL	0x0000000fffffffffULL

/* pow index/pointer load (subid = 2) */
#define POW_NULL_RD_LOAD_39_3			0x000000fffffffff8ULL
#define POW_NULL_RD_LOAD_2_0			0x0000000000000007ULL
#define	POW_NULL_RD_LOAD_2_0_SHIFT	0
#define	POW_NULL_RD_LOAD_39_3_SHIFT	3

#define POW_NULL_RD_LOAD_RESULT_63_2		0xfffffffffffffffcULL
#define POW_NULL_RD_LOAD_RESULT_STATUS		0x0000000000000003ULL

/* pow store operations */

#define POW_PHY_ADDR_STORE_ADDR			0x0000000fffffffffULL
#define	POW_PHY_ADDR_STORE_ADDR_SHIFT	0

#define POW_STORE_DATA_NO_SCHED			0x8000000000000000ULL
#define POW_STORE_DATA_62_61			0x6000000000000000ULL
#define POW_STORE_DATA_INDEX			0x1fff000000000000ULL
#define POW_STORE_DATA_OP			0x0000f00000000000ULL
#define POW_STORE_DATA_43_42			0x00000c0000000000ULL
#define POW_STORE_DATA_QOS			0x0000038000000000ULL
#define POW_STORE_DATA_GRP			0x0000007800000000ULL
#define POW_STORE_DATA_TYPE			0x0000000700000000ULL
#define POW_STORE_DATA_TAG			0x00000000ffffffffULL
#define	POW_STORE_DATA_NO_SCHED_SHIFT	63
#define	POW_STORE_DATA_62_61_SHIFT	61
#define	POW_STORE_DATA_INDEX_SHIFT	48
#define	POW_STORE_DATA_OP_SHIFT	44
#define	POW_STORE_DATA_43_42_SHIFT	42
#define	POW_STORE_DATA_QOS_SHIFT	39
#define	POW_STORE_DATA_GRP_SHIFT	35
#define	POW_STORE_DATA_TYPE_SHIFT	32
#define	POW_STORE_DATA_TAG_SHIFT	0

/* pow iobdma operations */

/* pow iobdma operations base*/
#define POW_IOBDMA_BASE_SCRADDR			0xff00000000000000ULL
#define POW_IOBDMA_BASE_LEN			0x00ff000000000000ULL
#define POW_IOBDMA_BASE_MAJOR_DID		0x0000f80000000000ULL
#define POW_IOBDMA_BASE_SUB_DID			0x0000070000000000ULL
#define POW_IOBDMA_BASE_39_0			0x000000ffffffffffULL
#define	POW_IOBDMA_BASE_SCRADDR_SHIFT	56
#define	POW_IOBDMA_BASE_SUB_DID_SHIFT	40
#define	POW_IOBDMA_BASE_39_0_SHIFT	0
#define	POW_IOBDMA_BASE_LEN_SHIFT	48
#define	POW_IOBDMA_BASE_MAJOR_DID_SHIFT	43

/* pow iobdma get work (subid = 0) */
#define POW_IOBDMA_GET_WORK_39_4		0x000000ffffffffffULL
#define POW_IOBDMA_GET_WORK_WAIT		0x0000000000000008ULL
#define POW_IOBDMA_GET_WORK_2_0			0x0000000000000007ULL
#define	POW_IOBDMA_GET_WORK_39_4_SHIFT	0
#define	POW_IOBDMA_GET_WORK_2_0_SHIFT	0
#define	POW_IOBDMA_GET_WORK_WAIT_SHIFT	3

#define POW_IOBDMA_GET_WORK_RESULT_NO_WORK	0x8000000000000000ULL
#define POW_IOBDMA_GET_WORK_RESULT_62_40	0x7fffff0000000000ULL
#define POW_IOBDMA_GET_WORK_RESULT_ADDR		0x000000ffffffffffULL

/* pow iobdma null rd (subid = 4) */
#define POW_IOBDMA_NULL_RD_39_0			0x000000ffffffffffULL
#define	POW_IOBDMA_NULL_RD_39_0_SHIFT	0

#define POW_IOBDMA_NULL_RD_RESULT_63_2		0xfffffffffffffffcULL
#define POW_IOBDMA_NULL_RD_RESULT_STATUS	0x0000000000000003ULL

/* ------------------------------------------------------------------------- */

/* Work Queue Entry */

#define	POW_WQE_WORD0_XXX_63_40			0xffffff0000000000ULL
#define	POW_WQE_WORD0_NEXT			0x000000ffffffffffULL
#define	POW_WQE_WORD0_NEXT_SHIFT	0

#define	POW_WQE_WORD1_XXX_63_42			0xfffffc0000000000ULL
#define	POW_WQE_WORD1_QOS			0x0000038000000000ULL
#define	POW_WQE_WORD1_GRP			0x0000007800000000ULL
#define	POW_WQE_WORD1_TT			0x0000000700000000ULL
#define	POW_WQE_WORD1_TAG			0x00000000ffffffffULL
#define	POW_WQE_WORD1_GRP_SHIFT	35
#define	POW_WQE_WORD1_QOS_SHIFT	39
#define	POW_WQE_WORD1_TT_SHIFT	32
#define	POW_WQE_WORD1_TAG_SHIFT	0

#endif /* _CN30XXPOWREG_H_ */

license: unknown


code:
/*	$OpenBSD: cn30xxpowvar.h,v 1.2 2014/08/11 18:29:56 miod Exp $	*/

/*
 * Copyright (c) 2007 Internet Initiative Japan, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _CN30XXPOWVAR_H_
#define _CN30XXPOWVAR_H_

#define POW_TAG_TYPE_ORDERED	0
#define POW_TAG_TYPE_ATOMIC	1
#define POW_TAG_TYPE_NULL	2
#define POW_TAG_TYPE_NULL_NULL	3

#define POW_TAG_OP_SWTAG		0
#define POW_TAG_OP_SWTAG_FULL		1
#define POW_TAG_OP_SWTAG_DESCHED	2
#define POW_TAG_OP_DESCHED		3
#define POW_TAG_OP_ADDWQ		4
#define POW_TAG_OP_UPD_WQP_GRP		5
#define POW_TAG_OP_CLR_NSCHED		7
#define POW_TAG_OP_NOP			15

#define POW_WAIT	1
#define POW_NO_WAIT	0

/* XXX */
struct cn30xxpow_softc {
	struct device		sc_dev;
	bus_space_tag_t		sc_regt;
	bus_space_handle_t	sc_regh;
	int			sc_port;
	int			sc_int_pc_base;
};

/* XXX */
struct cn30xxpow_attach_args {
	int			aa_port;
	bus_space_tag_t		aa_regt;
};

void			cn30xxpow_config(struct cn30xxpow_softc *, int);
void			*cn30xxpow_intr_establish(int, int,
			    void (*)(void *, uint64_t *),
			    void (*)(int *, int *, uint64_t, void *),
			    void *, char *);
void			cn30xxpow_error_int_enable(void *, int);
uint64_t		cn30xxpow_error_int_summary(void *);
int			cn30xxpow_ring_reduce(void *);
int			cn30xxpow_ring_grow(void *);
int			cn30xxpow_ring_size(void);
int			cn30xxpow_ring_intr(void);

#define	_POW_RD8(sc, off) \
	bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
#define	_POW_WR8(sc, off, v) \
	bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))
#define	_POW_GROUP_RD8(sc, pi, off) \
	bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, \
	    (off) + sizeof(uint64_t) * (pi)->pi_group)
#define	_POW_GROUP_WR8(sc, pi, off, v) \
	bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, \
	    (off) + sizeof(uint64_t) * (pi)->pi_group, (v))

extern struct cn30xxpow_softc	cn30xxpow_softc;

/* -------------------------------------------------------------------------- */

/* 5.11.1 Load Operations */

/* GET_WORK Loads */

static inline uint64_t
cn30xxpow_ops_get_work_load(
	int wait)			/* 0-1 */
{
	uint64_t ptr =
	    POW_OPERATION_BASE_IO_BIT |
	    __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
	    __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x00) |
	    __BITS64_SET(POW_GET_WORK_LOAD_WAIT, wait);

	return octeon_xkphys_read_8(ptr);
}

/* POW Status Loads */

/*
 * a) get_cur == 0, get_wqp == 0 (pend_tag)
 * b) get_cur == 0, get_wqp == 1 (pend_wqp)
 * c) get_cur == 1, get_wqp == 0, get_rev == 0 (cur_tag_next)
 * d) get_cur == 1, get_wqp == 0, get_rev == 1 (cur_tag_prev)
 * e) get_cur == 1, get_wqp == 1, get_rev == 0 (cur_wqp_next)
 * f) get_cur == 1, get_wqp == 1, get_rev == 1 (cur_wqp_prev)
 */

static inline uint64_t
cn30xxpow_ops_pow_status(
	int coreid,			/* 0-15 */
	int get_rev,			/* 0-1 */
	int get_cur,			/* 0-1 */
	int get_wqp)			/* 0-1 */
{
	uint64_t ptr =
	    POW_OPERATION_BASE_IO_BIT |
	    __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
	    __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x01) |
	    __BITS64_SET(POW_STATUS_LOAD_COREID, coreid) |
	    __BITS64_SET(POW_STATUS_LOAD_GET_REV, get_rev) |
	    __BITS64_SET(POW_STATUS_LOAD_GET_CUR, get_cur) |
	    __BITS64_SET(POW_STATUS_LOAD_GET_WQP, get_wqp);

	return octeon_xkphys_read_8(ptr);
}

/* POW Memory Loads */

/*
 * a) get_des == 0, get_wqp == 0 (tag)
 * b) get_des == 0, get_wqp == 1 (wqe)
 * c) get_des == 1 (desched)
 */

static inline uint64_t
cn30xxpow_ops_pow_memory(
	int index,			/* 0-2047 */
	int get_des,			/* 0-1 */
	int get_wqp)			/* 0-1 */
{
	uint64_t ptr =
	    POW_OPERATION_BASE_IO_BIT |
	    __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
	    __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x02) |
	    __BITS64_SET(POW_MEMORY_LOAD_INDEX, index) |
	    __BITS64_SET(POW_MEMORY_LOAD_GET_DES, get_des) |
	    __BITS64_SET(POW_MEMORY_LOAD_GET_WQP, get_wqp);

	return octeon_xkphys_read_8(ptr);
}

/* POW Index/Pointer Loads */

/*
 * a) get_rmt == 0, get_des_get_tail == 0
 * b) get_rmt == 0, get_des_get_tail == 1
 * c) get_rmt == 1, get_des_get_tail == 0
 * d) get_rmt == 1, get_des_get_tail == 1
 */

static inline uint64_t
cn30xxpow_ops_pow_idxptr(
	int qosgrp,			/* 0-7 */
	int get_des_get_tail,		/* 0-1 */
	int get_rmt)			/* 0-1 */
{
	uint64_t ptr =
	    POW_OPERATION_BASE_IO_BIT |
	    __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
	    __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x03) |
	    __BITS64_SET(POW_IDXPTR_LOAD_QOSGRP, qosgrp) |
	    __BITS64_SET(POW_IDXPTR_LOAD_GET_DES_GET_TAIL, get_des_get_tail) |
	    __BITS64_SET(POW_IDXPTR_LOAD_GET_RMT, get_rmt);

	return octeon_xkphys_read_8(ptr);
}

/* NULL_RD Loads */

static inline uint64_t
cn30xxpow_ops_null_rd_load(void)
{
	uint64_t ptr =
	    POW_OPERATION_BASE_IO_BIT |
	    __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
	    __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x04);

	return octeon_xkphys_read_8(ptr);
}

/* 5.11.2 IOBDMA Operations */

/*
 * XXXSEIL
 * ``subdid'' values are inverted between ``get_work_addr'' and ``null_read_id''
 * in CN30XX-HM-1.0 and CN31XX-HM-1.01.  (Corrected in CN50XX-HM-0.99A.)
 *
 * XXXSEIL
 * The ``scraddr'' part is index in 8 byte words, not address.  This is not
 * documented...
 */

/* GET_WORK IOBDMAs */

static inline void
cn30xxpow_ops_get_work_iobdma(
	int scraddr,			/* 0-2047 */
	int wait)			/* 0-1 */
{
 	/* ``scraddr'' part is index in 64-bit words, not address */
	const int scrindex = scraddr / sizeof(uint64_t);

        uint64_t args =
             __BITS64_SET(POW_IOBDMA_GET_WORK_WAIT, wait);
        uint64_t value =
            __BITS64_SET(POW_IOBDMA_BASE_SCRADDR, scrindex) |
            __BITS64_SET(POW_IOBDMA_BASE_LEN, 0x01) |
            __BITS64_SET(POW_IOBDMA_BASE_MAJOR_DID, 0x0c) |
            __BITS64_SET(POW_IOBDMA_BASE_SUB_DID, 0x00) |
            __BITS64_SET(POW_IOBDMA_BASE_39_0, args);

        octeon_iobdma_write_8(value);
}

/* NULL_RD IOBDMAs */

static inline void
cn30xxpow_ops_null_rd_iobdma(
	int scraddr)			/* 0-2047 */
{
 	/* ``scraddr'' part is index in 64-bit words, not address */
	const int scrindex = scraddr / sizeof(uint64_t);

        uint64_t value =
            __BITS64_SET(POW_IOBDMA_BASE_SCRADDR, scrindex) |
            __BITS64_SET(POW_IOBDMA_BASE_LEN, 0x01) |
            __BITS64_SET(POW_IOBDMA_BASE_MAJOR_DID, 0x0c) |
            __BITS64_SET(POW_IOBDMA_BASE_SUB_DID, 0x04) |
            __BITS64_SET(POW_IOBDMA_BASE_39_0, 0);

        octeon_iobdma_write_8(value);
}

/* 5.11.3 Store Operations */

static inline void
cn30xxpow_store(
	int subdid,			/* 0, 1, 3 */
	uint64_t addr,			/* 0-0x0000.000f.ffff.ffff */
	int no_sched,			/* 0, 1 */
	int index,			/* 0-8191 */
	int op,				/* 0-15 */
	int qos,			/* 0-7 */
	int grp,			/* 0-7 */
	int type,			/* 0-7 */
	uint32_t tag)			/* 0-0xffff.ffff */
{
	/* Physical Address to Store to POW */
	uint64_t ptr =
	    POW_OPERATION_BASE_IO_BIT |
	    __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) |
	    __BITS64_SET(POW_OPERATION_BASE_SUB_DID, subdid) |
	    __BITS64_SET(POW_PHY_ADDR_STORE_ADDR, addr);

	/* Store Data on Store to POW */
	uint64_t args =
	    __BITS64_SET(POW_STORE_DATA_NO_SCHED, no_sched) |
	    __BITS64_SET(POW_STORE_DATA_INDEX, index) |
	    __BITS64_SET(POW_STORE_DATA_OP, op) |
	    __BITS64_SET(POW_STORE_DATA_QOS, qos) |
	    __BITS64_SET(POW_STORE_DATA_GRP, grp) |
	    __BITS64_SET(POW_STORE_DATA_TYPE, type) |
	    __BITS64_SET(POW_STORE_DATA_TAG, tag);

	octeon_xkphys_write_8(ptr, args);
}

/* SWTAG */

static inline void
cn30xxpow_ops_swtag(int type, uint32_t tag)
{
	cn30xxpow_store(
		1,			/* subdid == 1 */
		0, 			/* addr (not used for SWTAG) */
		0,			/* no_sched (not used for SWTAG) */
		0,			/* index (not used for SWTAG) */
		POW_TAG_OP_SWTAG,	/* op == SWTAG */
		0,			/* qos (not used for SWTAG) */
		0,			/* grp (not used for SWTAG) */
		type,
		tag);
	/* switch to NULL completes immediately */
}

/* SWTAG_FULL */

static inline void
cn30xxpow_ops_swtag_full(paddr_t addr, int grp, int type, uint32_t tag)
{
	cn30xxpow_store(
		0,			/* subdid == 0 */
		addr,
		0,			/* no_sched (not used for SWTAG_FULL) */
		0,			/* index (not used for SWTAG_FULL) */
		POW_TAG_OP_SWTAG_FULL,	/* op == SWTAG_FULL */
		0,			/* qos (not used for SWTAG_FULL) */
		grp,
		type,
		tag);
}

/* SWTAG_DESCHED */

static inline void
cn30xxpow_ops_swtag_desched(int no_sched, int grp, int type, uint32_t tag)
{
	cn30xxpow_store(
		3,			/* subdid == 3 */
		0,			/* addr (not used for SWTAG_DESCHED) */
		no_sched,
		0,			/* index (not used for SWTAG_DESCHED) */
		POW_TAG_OP_SWTAG_DESCHED, /* op == SWTAG_DESCHED */
		0,			/* qos (not used for SWTAG_DESCHED) */
		grp,
		type,
		tag);
}

/* DESCHED */

static inline void
cn30xxpow_ops_desched(int no_sched)
{
	cn30xxpow_store(
		3,			/* subdid == 3 */
		0,			/* addr (not used for DESCHED) */
		no_sched,
		0,			/* index (not used for DESCHED) */
		POW_TAG_OP_DESCHED,	/* op == DESCHED */
		0,			/* qos (not used for DESCHED) */
		0,			/* grp (not used for DESCHED) */
		0,			/* type (not used for DESCHED) */
		0);			/* tag (not used for DESCHED) */
}

/* ADDWQ */

static inline void
cn30xxpow_ops_addwq(paddr_t addr, int qos, int grp, int type, uint32_t tag)
{
	cn30xxpow_store(
		1,			/* subdid == 1 */
		addr,
		0,			/* no_sched (not used for ADDWQ) */
		0,			/* index (not used for ADDWQ) */
		POW_TAG_OP_ADDWQ,	/* op == ADDWQ */
		qos,
		grp,
		type,
		tag);
}

/* UPD_WQP_GRP */

static inline void
cn30xxpow_ops_upd_wqp_grp(paddr_t addr, int grp)
{
	cn30xxpow_store(
		1,			/* subdid == 1 */
		addr,
		0,			/* no_sched (not used for UPD_WQP_GRP) */
		0,			/* index (not used for UPD_WQP_GRP) */
		POW_TAG_OP_UPD_WQP_GRP,	/* op == UPD_WQP_GRP */
		0,			/* qos (not used for UPD_WQP_GRP) */
		grp,
		0,			/* type (not used for UPD_WQP_GRP) */
		0);			/* tag (not used for UPD_WQP_GRP) */
}

/* CLR_NSCHED */

static inline void
cn30xxpow_ops_clr_nsched(paddr_t addr, int index)
{
	cn30xxpow_store(
		1,			/* subdid == 1 */
		addr,
		0,			/* no_sched (not used for CLR_NSCHED) */
		index,
		POW_TAG_OP_CLR_NSCHED,	/* op == CLR_NSCHED */
		0,			/* qos (not used for CLR_NSCHED) */
		0,			/* grp (not used for CLR_NSCHED) */
		0,			/* type (not used for CLR_NSCHED) */
		0);			/* tag (not used for CLR_NSCHED) */
}

/* NOP */

static inline void
cn30xxpow_ops_nop(void)
{
	cn30xxpow_store(
		1,			/* subdid == 1 */
		0,			/* addr (not used for NOP) */
		0,			/* no_sched (not used for NOP) */
		0,			/* index (not used for NOP) */
		POW_TAG_OP_NOP,		/* op == NOP */
		0,			/* qos (not used for NOP) */
		0,			/* grp (not used for NOP) */
		0,			/* type (not used for NOP) */
		0);			/* tag (not used for NOP) */
}

/* -------------------------------------------------------------------------- */

/*
 * global functions
 */
void		cn30xxpow_work_request_async(uint64_t, uint64_t);
uint64_t	*cn30xxpow_work_response_async(uint64_t);
void		cn30xxpow_ops_swtag(int, uint32_t);
void		cn30xxpow_intr_set_freedback_queue(int, void *);

static inline void
cn30xxpow_config_int_pc(struct cn30xxpow_softc *sc, int unit)
{
	uint64_t wq_int_pc;
	uint64_t pc_thr;
	static uint64_t cpu_clock_hz;

	if (cpu_clock_hz == 0)
		cpu_clock_hz  = curcpu()->ci_hw.clock;

#if 0
	/* from Documents */
	/*
 	 * => counter value is POW_WQ_INT_PC[PC_THR] * 256 + 255
	 * => counter is decremented every CPU clock
	 * => counter is reset when interrupt occurs
	 *
	 *      cpu_clock_per_sec
	 *              = cpu_clock_mhz * 1000000
	 *      cpu_clock_per_msec
	 *              = cpu_clock_mhz * 1000
	 *      cpu_clock_per_usec
	 *              = cpu_clock_mhz
 	 *
	 *      pc_thr_for_1sec * 256 + 255
	 *              = cpu_clock_mhz * 1000000
	 *      pc_thr_for_1sec
	 *              = ((cpu_clock_mhz * 1000000) - 255) / 256
	 *
	 *      pc_thr_for_1msec * 256 + 255
	 *              = cpu_clock_mhz * 1000
	 *      pc_thr_for_1msec
	 *              = ((cpu_clock_mhz * 1000) - 255) / 256
	 *
	 *      pc_thr_for_1usec * 256 + 255
	 *              = cpu_clock_mhz
	 *      pc_thr_for_1usec
	 *              = (cpu_clock_mhz - 255) / 256
	 */
	pc_thr = (((cpu_clock_hz / 1000000) * (unit)) - 255) / 256;
#else
	pc_thr = (cpu_clock_hz) / (unit * 16 * 256);
#endif
	wq_int_pc = pc_thr << POW_WQ_INT_PC_PC_THR_SHIFT;
	_POW_WR8(sc, POW_WQ_INT_PC_OFFSET, wq_int_pc);
}

static inline void
cn30xxpow_config_int_pc_rate(struct cn30xxpow_softc *sc, int rate)
{
	cn30xxpow_config_int_pc(sc, sc->sc_int_pc_base / rate);
}

#endif /* _CN30XXPOWVAR_H_ */


code:
/*	$OpenBSD: cn30xxsmi.c,v 1.3 2014/08/11 18:08:17 miod Exp $	*/

/*
 * Copyright (c) 2007 Internet Initiative Japan, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>

#include <machine/octeonvar.h>

#include <octeon/dev/cn30xxfpavar.h>
#include <octeon/dev/cn30xxpipreg.h>
#include <octeon/dev/cn30xxsmireg.h>
#include <octeon/dev/cn30xxsmivar.h>

void	cn30xxsmi_enable(struct cn30xxsmi_softc *);

/* XXX */
void
cn30xxsmi_init(struct cn30xxsmi_attach_args *aa,
    struct cn30xxsmi_softc **rsc)
{
	struct cn30xxsmi_softc *sc;
	int status;

	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
	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, SMI_BASE, SMI_SIZE, 0,
	    &sc->sc_regh);
	if (status != 0)
		panic("can't map %s space", "smi register");

	cn30xxsmi_enable(sc);

	*rsc = sc;
}

#define	_SMI_RD8(sc, off) \
	bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
#define	_SMI_WR8(sc, off, v) \
	bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))

int
cn30xxsmi_read(struct cn30xxsmi_softc *sc, int phy_addr, int reg)
{
	uint64_t smi_rd;
	int timo;

	_SMI_WR8(sc, SMI_CMD_OFFSET, SMI_CMD_PHY_OP |
	    (phy_addr << SMI_CMD_PHY_ADR_SHIFT) |
	    (reg << SMI_CMD_REG_ADR_SHIFT));

	timo = 10000;
	smi_rd = _SMI_RD8(sc, SMI_RD_DAT_OFFSET);
	while (ISSET(smi_rd, SMI_RD_DAT_PENDING)) {
		if (timo-- == 0)
			break;
		delay(10);
		smi_rd = _SMI_RD8(sc, SMI_RD_DAT_OFFSET);
	}
	if (ISSET(smi_rd, SMI_RD_DAT_PENDING)) {
		return -1;
	}

	return ISSET(smi_rd, SMI_RD_DAT_VAL) ? (smi_rd & SMI_RD_DAT_DAT) : 0;
}

void
cn30xxsmi_write(struct cn30xxsmi_softc *sc, int phy_addr, int reg, int value)
{
	uint64_t smi_wr;
	int timo;

	smi_wr = 0;
	SET(smi_wr, value);
	_SMI_WR8(sc, SMI_WR_DAT_OFFSET, smi_wr);

	_SMI_WR8(sc, SMI_CMD_OFFSET, (phy_addr << SMI_CMD_PHY_ADR_SHIFT) |
	    (reg << SMI_CMD_REG_ADR_SHIFT));

	timo = 10000;
	smi_wr = _SMI_RD8(sc, SMI_WR_DAT_OFFSET);
	while (ISSET(smi_wr, SMI_WR_DAT_PENDING)) {
		if (timo-- == 0)
			break;
		delay(10);
		smi_wr = _SMI_RD8(sc, SMI_WR_DAT_OFFSET);
	}
	if (ISSET(smi_wr, SMI_WR_DAT_PENDING)) {
		/* XXX log */
		printf("ERROR: cnmac_mii_writereg(0x%x, 0x%x, 0x%x) timed out.\n",
		    phy_addr, reg, value);
	}
}

void
cn30xxsmi_enable(struct cn30xxsmi_softc *sc)
{
	_SMI_WR8(sc, SMI_EN_OFFSET, SMI_EN_EN);
}

void
cn30xxsmi_set_clock(struct cn30xxsmi_softc *sc, uint64_t clock)
{
	_SMI_WR8(sc, SMI_CLK_OFFSET, clock);
}


code:
/*
 * THIS FILE IS AUTOMATICALLY GENERATED
 * DONT EDIT THIS FILE
 */

/*	$OpenBSD: cn30xxsmireg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $	*/

/*
 * Copyright (c) 2007 Internet Initiative Japan, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Cavium Networks OCTEON CN30XX Hardware Reference Manual
 * CN30XX-HM-1.0
 * 18.3 SMI Registers
 */

#ifndef _CN30XXSMIREG_H_
#define _CN30XXSMIREG_H_

#define	SMI_CMD					0x0001180000001800ULL
#define	SMI_WR_DAT				0x0001180000001808ULL
#define	SMI_RD_DAT				0x0001180000001810ULL
#define	SMI_CLK					0x0001180000001818ULL
#define	SMI_EN					0x0001180000001820ULL

#define	SMI_CMD_OFFSET				0x00ULL
#define	SMI_WR_DAT_OFFSET			0x08ULL
#define	SMI_RD_DAT_OFFSET			0x10ULL
#define	SMI_CLK_OFFSET				0x18ULL
#define	SMI_EN_OFFSET				0x20ULL

#define SMI_BASE				0x0001180000001800ULL
#define SMI_SIZE				0x028ULL

/* SMI CMD */
#define SMI_CMD_63_17			0xfffffffffffe0000ULL
#define SMI_CMD_PHY_OP			0x0000000000010000ULL
#define SMI_CMD_15_13			0x000000000000e000ULL
#define SMI_CMD_PHY_ADR			0x0000000000001f00ULL
#define  SMI_CMD_PHY_ADR_SHIFT		8
#define SMI_CMD_7_5			0x00000000000000e0ULL
#define SMI_CMD_REG_ADR			0x000000000000001fULL
#define  SMI_CMD_REG_ADR_SHIFT		0

/* SMI_WR_DAT */
#define SMI_WR_DAT_63_18		0xfffffffffffc0000ULL
#define SMI_WR_DAT_PENDING		0x0000000000020000ULL
#define SMI_WR_DAT_VAL			0x0000000000010000ULL
#define SMI_WR_DAT_DAT			0x000000000000ffffULL

/* SMI_RD_DAT */
#define SMI_RD_DAT_63_18		0xfffffffffffc0000ULL
#define SMI_RD_DAT_PENDING		0x0000000000020000ULL
#define SMI_RD_DAT_VAL			0x0000000000010000ULL
#define SMI_RD_DAT_DAT			0x000000000000ffffULL

/* SMI_CLK */
#define SMI_CLK_63_21			0xffffffffffe00000ULL
#define SMI_CLK_SAMPLE_HI		0x00000000001f0000ULL
#define SMI_CLK_15_14			0x000000000000c000ULL
#define SMI_CLK_CLK_IDLE		0x0000000000002000ULL
#define SMI_CLK_PREAMBLE		0x0000000000001000ULL
#define SMI_CLK_SAMPLE			0x0000000000000f00ULL
#define SMI_CLK_PHASE			0x00000000000000ffULL

/* SMI_EN */
#define SMI_EN_63_1			0xfffffffffffffffeULL
#define SMI_EN_EN			0x0000000000000001ULL

/* XXX */

#endif /* _CN30XXSMIREG_H_ */


code:
/*	$OpenBSD: cn30xxsmivar.h,v 1.2 2011/06/24 02:13:23 yasuoka Exp $	*/

/*
 * Copyright (c) 2007 Internet Initiative Japan, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _CN30XXSMIVAR_H_
#define _CN30XXSMIVAR_H_

/* XXX */
struct cn30xxsmi_softc {
	int			sc_port;
	bus_space_tag_t		sc_regt;
	bus_space_handle_t	sc_regh;
};

/* XXX */
struct cn30xxsmi_attach_args {
	int			aa_port;
	bus_space_tag_t		aa_regt;
};

void			cn30xxsmi_init(struct cn30xxsmi_attach_args *,
			    struct cn30xxsmi_softc **);
int			cn30xxsmi_read(struct cn30xxsmi_softc *, int, int);
void			cn30xxsmi_write(struct cn30xxsmi_softc *, int, int, int);
void			cn30xxsmi_set_clock(struct cn30xxsmi_softc *, uint64_t);

#endif


code:
/*	$OpenBSD: cn30xxuart.c,v 1.7 2015/02/05 23:29:33 uebayasi Exp $	*/

/*
 * Copyright (c) 2001-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/tty.h>
#include <sys/conf.h>

#include <machine/octeonvar.h>
#include <machine/autoconf.h>
#include <machine/bus.h>

#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>
#include <dev/cons.h>

#include <octeon/dev/iobusvar.h>
#include <octeon/dev/uartbusvar.h>
#include <octeon/dev/cn30xxuartreg.h>

int	cn30xxuart_probe(struct device *, void *, void *);
void	cn30xxuart_attach(struct device *, struct device *, void *);

struct cfattach cn30xxuart_ca = {
	sizeof(struct com_softc), cn30xxuart_probe, cn30xxuart_attach
};

extern struct cfdriver com_cd;

cons_decl(cn30xxuart);

#define  USR_TXFIFO_NOTFULL		2

/* XXX: What is this used for? Removed from stand/boot/uart.c -r1.2 */
static int delay_changed = 1;
int cn30xxuart_delay(void);
void cn30xxuart_wait_txhr_empty(int);

int
cn30xxuart_probe(struct device *parent, void *match, void *aux)
{
	struct cfdata *cf = match;
	struct uartbus_attach_args *uba = aux;
	bus_space_tag_t iot = uba->uba_memt;
	bus_space_handle_t ioh;
	int rv = 0, console;

	if (strcmp(uba->uba_name, com_cd.cd_name) != 0)
		return 0;

	console = 1;

	/* if it's in use as console, it's there. */
	if (!(console && !comconsattached)) {
		if (bus_space_map(iot, uba->uba_baseaddr, COM_NPORTS, 0, &ioh)) {
			printf(": can't map uart registers\n");
			return 1;
		}
		rv = comprobe1(iot, ioh);
	} else
		rv = 1;

	/* make a config stanza with exact locators match over a generic line */
	if (cf->cf_loc[0] != -1)
		rv += rv;

	return rv;
}

void
cn30xxuart_attach(struct device *parent, struct device *self, void *aux)
{
	struct com_softc *sc = (void *)self;
	struct uartbus_attach_args *uba = aux;
	int console;

	console = 1;

	sc->sc_iot = uba->uba_memt;
	sc->sc_iobase = uba->uba_baseaddr;
	sc->sc_hwflags = 0;
	sc->sc_swflags = 0;
	sc->sc_frequency = octeon_ioclock_speed();
	sc->sc_uarttype = COM_UART_16550;

	/* if it's in use as console, it's there. */
	if (bus_space_map(sc->sc_iot, sc->sc_iobase, COM_NPORTS, 0, &sc->sc_ioh)) {
		printf(": can't map uart registers\n");
		return;
	}

	if (console && !comconsattached) {
		/*
		 * If we are the console, reuse the existing bus_space
		 * information, so that comcnattach() invokes bus_space_map()
		 * with correct parameters.
		 */

		if (comcnattach(sc->sc_iot, sc->sc_iobase, 115200,
		    sc->sc_frequency, (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8))
			panic("can't setup serial console");
	}

	com_attach_subr(sc);

	octeon_intr_establish(uba->uba_intr, IPL_TTY, comintr,
	    (void *)sc, sc->sc_dev.dv_xname);
}

/*
 * Early console routines.
 */
int
cn30xxuart_delay(void)
{
	int divisor;
	u_char lcr;
	static int d = 0;

	if (!delay_changed)
		return d;
	delay_changed = 0;
	lcr = octeon_xkphys_read_8(MIO_UART0_LCR);
	octeon_xkphys_write_8(MIO_UART0_LCR, lcr | LCR_DLAB);
	divisor = octeon_xkphys_read_8(MIO_UART0_DLL) |
		octeon_xkphys_read_8(MIO_UART0_DLH) << 8;
	octeon_xkphys_write_8(MIO_UART0_LCR, lcr);

	return 10; /* return an approx delay value */
}

void
cn30xxuart_wait_txhr_empty(int d)
{
	while (((octeon_xkphys_read_8(MIO_UART0_LSR) & LSR_TXRDY) == 0) &&
	    ((octeon_xkphys_read_8(MIO_UART0_USR) & USR_TXFIFO_NOTFULL) == 0))
		delay(d);
}

void
cn30xxuartcninit(struct consdev *consdev)
{
}

void
cn30xxuartcnprobe(struct consdev *consdev)
{
}

void
cn30xxuartcnpollc(dev_t dev, int c)
{
}

void
cn30xxuartcnputc(dev_t dev, int c)
{
	int d;

	/* 1/10th the time to transmit 1 character (estimate). */
	d = cn30xxuart_delay();
	cn30xxuart_wait_txhr_empty(d);
	octeon_xkphys_write_8(MIO_UART0_RBR, (uint8_t)c);
	cn30xxuart_wait_txhr_empty(d);
}

int
cn30xxuartcngetc(dev_t dev)
{
	int c, d;

	/* 1/10th the time to transmit 1 character (estimate). */
	d = cn30xxuart_delay();

	while ((octeon_xkphys_read_8(MIO_UART0_LSR) & LSR_RXRDY) == 0)
		delay(d);

	c = (uint8_t)octeon_xkphys_read_8(MIO_UART0_RBR);

	return (c);
}


code:
/*
 * THIS FILE IS AUTOMATICALLY GENERATED
 * DONT EDIT THIS FILE
 */

/*	$OpenBSD: cn30xxuartreg.h,v 1.1 2011/06/16 11:22:30 syuu Exp $	*/

/*
 * Copyright (c) 2007 Internet Initiative Japan, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Cavium Networks OCTEON CN30XX Hardware Reference Manual
 * CN30XX-HM-1.0
 * 16.4 UART Registers
 */

#ifndef _CN30XXUARTREG_H_
#define _CN30XXUARTREG_H_

/* ---- register addresses */

#define	MIO_UART0_RBR				0x0001180000000800ULL
#define	MIO_UART0_IER				0x0001180000000808ULL
#define	MIO_UART0_IIR				0x0001180000000810ULL
#define	MIO_UART0_LCR				0x0001180000000818ULL
#define	MIO_UART0_MCR				0x0001180000000820ULL
#define	MIO_UART0_LSR				0x0001180000000828ULL
#define	MIO_UART0_MSR				0x0001180000000830ULL
#define	MIO_UART0_SCR				0x0001180000000838ULL
#define	MIO_UART0_THR				0x0001180000000840ULL
#define	MIO_UART0_FCR				0x0001180000000850ULL
#define	MIO_UART0_DLL				0x0001180000000880ULL
#define	MIO_UART0_DLH				0x0001180000000888ULL
#define	MIO_UART0_FAR				0x0001180000000920ULL
#define	MIO_UART0_TFR				0x0001180000000928ULL
#define	MIO_UART0_RFW				0x0001180000000930ULL
#define	MIO_UART0_USR				0x0001180000000938ULL
#define	MIO_UART0_TFL				0x0001180000000a00ULL
#define	MIO_UART0_RFL				0x0001180000000a08ULL
#define	MIO_UART0_SRR				0x0001180000000a10ULL
#define	MIO_UART0_SRTS				0x0001180000000a18ULL
#define	MIO_UART0_SBCR				0x0001180000000a20ULL
#define	MIO_UART0_SFE				0x0001180000000a30ULL
#define	MIO_UART0_SRT				0x0001180000000a38ULL
#define	MIO_UART0_STT				0x0001180000000b00ULL
#define	MIO_UART0_HTX				0x0001180000000b08ULL
#define	MIO_UART1_RBR				0x0001180000000c00ULL
#define	MIO_UART1_IER				0x0001180000000c08ULL
#define	MIO_UART1_IIR				0x0001180000000c10ULL
#define	MIO_UART1_LCR				0x0001180000000c18ULL
#define	MIO_UART1_MCR				0x0001180000000c20ULL
#define	MIO_UART1_LSR				0x0001180000000c28ULL
#define	MIO_UART1_MSR				0x0001180000000c30ULL
#define	MIO_UART1_SCR				0x0001180000000c38ULL
#define	MIO_UART1_THR				0x0001180000000c40ULL
#define	MIO_UART1_FCR				0x0001180000000c50ULL
#define	MIO_UART1_DLL				0x0001180000000c80ULL
#define	MIO_UART1_DLH				0x0001180000000c88ULL
#define	MIO_UART1_FAR				0x0001180000000d20ULL
#define	MIO_UART1_TFR				0x0001180000000d28ULL
#define	MIO_UART1_RFW				0x0001180000000d30ULL
#define	MIO_UART1_USR				0x0001180000000d38ULL
#define	MIO_UART1_TFL				0x0001180000000e00ULL
#define	MIO_UART1_RFL				0x0001180000000e08ULL
#define	MIO_UART1_SRR				0x0001180000000e10ULL
#define	MIO_UART1_SRTS				0x0001180000000e18ULL
#define	MIO_UART1_SBCR				0x0001180000000e20ULL
#define	MIO_UART1_SFE				0x0001180000000e30ULL
#define	MIO_UART1_SRT				0x0001180000000e38ULL
#define	MIO_UART1_STT				0x0001180000000f00ULL
#define	MIO_UART1_HTX				0x0001180000000f08ULL

/* ---- bitmask_snprintf */

/* XXX */

/* ---- bus_space */

#define	MIO_UART0_BASE				0x0001180000000800ULL
#define	MIO_UART1_BASE				0x0001180000000c00ULL

#define	MIO_UART_RBR_OFFSET			0x0000
#define	MIO_UART_IER_OFFSET			0x0008
#define	MIO_UART_IIR_OFFSET			0x0010
#define	MIO_UART_LCR_OFFSET			0x0018
#define	MIO_UART_MCR_OFFSET			0x0020
#define	MIO_UART_LSR_OFFSET			0x0028
#define	MIO_UART_MSR_OFFSET			0x0030
#define	MIO_UART_SCR_OFFSET			0x0038
#define	MIO_UART_THR_OFFSET			0x0040
#define	MIO_UART_FCR_OFFSET			0x0050
#define	MIO_UART_DLL_OFFSET			0x0080
#define	MIO_UART_DLH_OFFSET			0x0088
#define	MIO_UART_FAR_OFFSET			0x0120
#define	MIO_UART_TFR_OFFSET			0x0128
#define	MIO_UART_RFW_OFFSET			0x0130
#define	MIO_UART_USR_OFFSET			0x0138
#define	MIO_UART_TFL_OFFSET			0x0200
#define	MIO_UART_RFL_OFFSET			0x0208
#define	MIO_UART_SRR_OFFSET			0x0210
#define	MIO_UART_SRTS_OFFSET			0x0218
#define	MIO_UART_SBCR_OFFSET			0x0220
#define	MIO_UART_SFE_OFFSET			0x0230
#define	MIO_UART_SRT_OFFSET			0x0238
#define	MIO_UART_STT_OFFSET			0x0300
#define	MIO_UART_HTX_OFFSET			0x0308

#endif /* _CN30XXUARTREG_H_ */