xref: /netbsd-src/sys/arch/mips/cavium/dev/octeon_powvar.h (revision 7cfbdc5be92d87a593315a9b8f4d90200afdf934)
1*7cfbdc5bSsimonb /*	$NetBSD: octeon_powvar.h,v 1.7 2020/06/23 05:15:33 simonb Exp $	*/
2f693c922Shikaru 
3f693c922Shikaru /*
4f693c922Shikaru  * Copyright (c) 2007 Internet Initiative Japan, Inc.
5f693c922Shikaru  * All rights reserved.
6f693c922Shikaru  *
7f693c922Shikaru  * Redistribution and use in source and binary forms, with or without
8f693c922Shikaru  * modification, are permitted provided that the following conditions
9f693c922Shikaru  * are met:
10f693c922Shikaru  * 1. Redistributions of source code must retain the above copyright
11f693c922Shikaru  *    notice, this list of conditions and the following disclaimer.
12f693c922Shikaru  * 2. Redistributions in binary form must reproduce the above copyright
13f693c922Shikaru  *    notice, this list of conditions and the following disclaimer in the
14f693c922Shikaru  *    documentation and/or other materials provided with the distribution.
15f693c922Shikaru  *
16f693c922Shikaru  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17f693c922Shikaru  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18f693c922Shikaru  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19f693c922Shikaru  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20f693c922Shikaru  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21f693c922Shikaru  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22f693c922Shikaru  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23f693c922Shikaru  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24f693c922Shikaru  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25f693c922Shikaru  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26f693c922Shikaru  * SUCH DAMAGE.
27f693c922Shikaru  */
28f693c922Shikaru 
29f693c922Shikaru #ifndef _OCTEON_POWVAR_H_
30f693c922Shikaru #define _OCTEON_POWVAR_H_
31f693c922Shikaru 
32f693c922Shikaru #include <sys/cpu.h>
33f693c922Shikaru 
34b9fcd28bSsimonb #include <mips/cavium/octeonreg.h>
35b9fcd28bSsimonb 
36f693c922Shikaru #define POW_TAG_TYPE_ORDERED	0
37f693c922Shikaru #define POW_TAG_TYPE_ATOMIC	1
38f693c922Shikaru #define POW_TAG_TYPE_NULL	2
39f693c922Shikaru #define POW_TAG_TYPE_NULL_NULL	3
40f693c922Shikaru 
41f693c922Shikaru #define POW_TAG_OP_SWTAG		0
42f693c922Shikaru #define POW_TAG_OP_SWTAG_FULL		1
43f693c922Shikaru #define POW_TAG_OP_SWTAG_DESCHED	2
44f693c922Shikaru #define POW_TAG_OP_DESCHED		3
45f693c922Shikaru #define POW_TAG_OP_ADDWQ		4
46f693c922Shikaru #define POW_TAG_OP_UPD_WQP_GRP		5
47f693c922Shikaru #define POW_TAG_OP_CLR_NSCHED		7
48f693c922Shikaru #define POW_TAG_OP_NOP			15
49f693c922Shikaru 
50f693c922Shikaru #define POW_WAIT	1
51f693c922Shikaru #define POW_NO_WAIT	0
52f693c922Shikaru 
53*7cfbdc5bSsimonb #define	POW_WORKQ_IRQ(group)		(group)
54*7cfbdc5bSsimonb 
55f693c922Shikaru /* XXX */
563f508e4dSsimonb struct octpow_softc {
57f693c922Shikaru 	device_t		sc_dev;
58f693c922Shikaru 	bus_space_tag_t		sc_regt;
59f693c922Shikaru 	bus_space_handle_t	sc_regh;
60f693c922Shikaru 	int			sc_port;
61f693c922Shikaru 	int			sc_int_pc_base;
62f693c922Shikaru };
63f693c922Shikaru 
64f693c922Shikaru /* XXX */
653f508e4dSsimonb struct octpow_attach_args {
66f693c922Shikaru 	int			aa_port;
67f693c922Shikaru 	bus_space_tag_t		aa_regt;
68f693c922Shikaru };
69f693c922Shikaru 
703f508e4dSsimonb void		octpow_config(struct octpow_softc *, int);
713f508e4dSsimonb void		octpow_error_int_enable(void *, int);
723f508e4dSsimonb uint64_t	octpow_error_int_summary(void *);
733f508e4dSsimonb int		octpow_ring_reduce(void *);
743f508e4dSsimonb int		octpow_ring_grow(void *);
753f508e4dSsimonb int		octpow_ring_size(void);
763f508e4dSsimonb int		octpow_ring_intr(void);
77f693c922Shikaru 
78f693c922Shikaru #define	_POW_RD8(sc, off) \
79f693c922Shikaru 	bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off))
80f693c922Shikaru #define	_POW_WR8(sc, off, v) \
81f693c922Shikaru 	bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v))
82f693c922Shikaru #define	_POW_GROUP_RD8(sc, pi, off) \
83f693c922Shikaru 	bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, \
84f693c922Shikaru 	    (off) + sizeof(uint64_t) * (pi)->pi_group)
85f693c922Shikaru #define	_POW_GROUP_WR8(sc, pi, off, v) \
86f693c922Shikaru 	bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, \
87f693c922Shikaru 	    (off) + sizeof(uint64_t) * (pi)->pi_group, (v))
88f693c922Shikaru 
893f508e4dSsimonb extern struct octpow_softc	octpow_softc;
90f693c922Shikaru 
91f693c922Shikaru /* -------------------------------------------------------------------------- */
92f693c922Shikaru 
93f693c922Shikaru /* Load Operations */
94f693c922Shikaru 
95f693c922Shikaru /* GET_WORK Loads */
96f693c922Shikaru 
9787fd18f8Schristos static __inline uint64_t
octpow_ops_get_work_load(int wait)983f508e4dSsimonb octpow_ops_get_work_load(
99f693c922Shikaru 	int wait)			/* 0-1 */
100f693c922Shikaru {
101f693c922Shikaru 	uint64_t ptr =
102b9fcd28bSsimonb 	    OCTEON_ADDR_IO_DID(POW_MAJOR_DID, POW_OP_SUBDID_GET_WORK) |
103b9fcd28bSsimonb 	    (wait ? POW_GET_WORK_LOAD_WAIT : 0);
104f693c922Shikaru 
105f693c922Shikaru 	return octeon_xkphys_read_8(ptr);
106f693c922Shikaru }
107f693c922Shikaru 
108f693c922Shikaru /* IOBDMA Operations */
109f693c922Shikaru 
110f693c922Shikaru /* ``subdid'' values are inverted between ``get_work_addr'' and ``null_read_id'' */
111f693c922Shikaru 
112f693c922Shikaru /* The ``scraddr'' part is index in 8 byte words, not address. */
113f693c922Shikaru 
114f693c922Shikaru /* GET_WORK IOBDMAs */
115f693c922Shikaru 
11687fd18f8Schristos static __inline void
octpow_ops_get_work_iobdma(int scraddr,int wait)1173f508e4dSsimonb octpow_ops_get_work_iobdma(
118f693c922Shikaru 	int scraddr,			/* 0-2047 */
119f693c922Shikaru 	int wait)			/* 0-1 */
120f693c922Shikaru {
121f693c922Shikaru  	/* ``scraddr'' part is index in 64-bit words, not address */
122f693c922Shikaru 	const int scrindex = scraddr / sizeof(uint64_t);
123f693c922Shikaru 
124b9fcd28bSsimonb 	uint64_t value = IOBDMA_CREATE(POW_MAJOR_DID,
125b9fcd28bSsimonb 	    POW_IOBDMA_SUBDID_GET_WORK, scrindex, POW_IOBDMA_LEN,
126b9fcd28bSsimonb 	    wait ? POW_IOBDMA_GET_WORK_WAIT : 0);
127f693c922Shikaru 
128f693c922Shikaru         octeon_iobdma_write_8(value);
129f693c922Shikaru }
130f693c922Shikaru 
131f693c922Shikaru /* NULL_RD IOBDMAs */
132f693c922Shikaru 
13387fd18f8Schristos static __inline void
octpow_ops_null_rd_iobdma(int scraddr)1343f508e4dSsimonb octpow_ops_null_rd_iobdma(
135f693c922Shikaru 	int scraddr)			/* 0-2047 */
136f693c922Shikaru {
137f693c922Shikaru  	/* ``scraddr'' part is index in 64-bit words, not address */
138f693c922Shikaru 	const int scrindex = scraddr / sizeof(uint64_t);
139f693c922Shikaru 
140b9fcd28bSsimonb 	uint64_t value = IOBDMA_CREATE(POW_MAJOR_DID,
141b9fcd28bSsimonb 	    POW_IOBDMA_SUBDID_NULL_RD, scrindex, POW_IOBDMA_LEN, 0);
142f693c922Shikaru 
143f693c922Shikaru         octeon_iobdma_write_8(value);
144f693c922Shikaru }
145f693c922Shikaru 
146f693c922Shikaru /* Store Operations */
147f693c922Shikaru 
14887fd18f8Schristos static __inline void
octpow_store(int subdid,uint64_t addr,int no_sched,int index,int op,int qos,int grp,int type,uint32_t tag)1493f508e4dSsimonb octpow_store(
150f693c922Shikaru 	int subdid,			/* 0, 1, 3 */
151f693c922Shikaru 	uint64_t addr,			/* 0-0x0000.000f.ffff.ffff */
152f693c922Shikaru 	int no_sched,			/* 0, 1 */
153f693c922Shikaru 	int index,			/* 0-8191 */
154f693c922Shikaru 	int op,				/* 0-15 */
155f693c922Shikaru 	int qos,			/* 0-7 */
156f693c922Shikaru 	int grp,			/* 0-7 */
157f693c922Shikaru 	int type,			/* 0-7 */
158f693c922Shikaru 	uint32_t tag)			/* 0-0xffff.ffff */
159f693c922Shikaru {
160f693c922Shikaru 	/* Physical Address to Store to POW */
161b9fcd28bSsimonb 	uint64_t ptr = OCTEON_ADDR_IO_DID(POW_MAJOR_DID, subdid) |
162b9fcd28bSsimonb 	    __SHIFTIN(addr, POW_PHY_ADDR_STORE_ADDR);
163f693c922Shikaru 
164f693c922Shikaru 	/* Store Data on Store to POW */
165f693c922Shikaru 	uint64_t args =
166b9fcd28bSsimonb 	    __SHIFTIN(no_sched, POW_STORE_DATA_NO_SCHED) |
167b9fcd28bSsimonb 	    __SHIFTIN(index, POW_STORE_DATA_INDEX) |
168b9fcd28bSsimonb 	    __SHIFTIN(op, POW_STORE_DATA_OP) |
169b9fcd28bSsimonb 	    __SHIFTIN(qos, POW_STORE_DATA_QOS) |
170b9fcd28bSsimonb 	    __SHIFTIN(grp, POW_STORE_DATA_GRP) |
171b9fcd28bSsimonb 	    __SHIFTIN(type, POW_STORE_DATA_TYPE) |
172b9fcd28bSsimonb 	    __SHIFTIN(tag, POW_STORE_DATA_TAG);
173f693c922Shikaru 
174f693c922Shikaru 	octeon_xkphys_write_8(ptr, args);
175f693c922Shikaru }
176f693c922Shikaru 
177f693c922Shikaru /* SWTAG */
178f693c922Shikaru 
17987fd18f8Schristos static __inline void
octpow_ops_swtag(int type,uint32_t tag)1803f508e4dSsimonb octpow_ops_swtag(int type, uint32_t tag)
181f693c922Shikaru {
182b9fcd28bSsimonb 
1833f508e4dSsimonb 	octpow_store(
184b9fcd28bSsimonb 		POW_STORE_SUBDID_OTHER,
185f693c922Shikaru 		0, 			/* addr (not used for SWTAG) */
186f693c922Shikaru 		0,			/* no_sched (not used for SWTAG) */
187f693c922Shikaru 		0,			/* index (not used for SWTAG) */
188f693c922Shikaru 		POW_TAG_OP_SWTAG,	/* op == SWTAG */
189f693c922Shikaru 		0,			/* qos (not used for SWTAG) */
190f693c922Shikaru 		0,			/* grp (not used for SWTAG) */
191f693c922Shikaru 		type,
192f693c922Shikaru 		tag);
193f693c922Shikaru 	/* switch to NULL completes immediately */
194f693c922Shikaru }
195f693c922Shikaru 
196f693c922Shikaru /* SWTAG_FULL */
197f693c922Shikaru 
19887fd18f8Schristos static __inline void
octpow_ops_swtag_full(paddr_t addr,int grp,int type,uint32_t tag)1993f508e4dSsimonb octpow_ops_swtag_full(paddr_t addr, int grp, int type, uint32_t tag)
200f693c922Shikaru {
201b9fcd28bSsimonb 
2023f508e4dSsimonb 	octpow_store(
203b9fcd28bSsimonb 		POW_STORE_SUBDID_SWTAG_FULL,
204f693c922Shikaru 		addr,
205f693c922Shikaru 		0,			/* no_sched (not used for SWTAG_FULL) */
206f693c922Shikaru 		0,			/* index (not used for SWTAG_FULL) */
207f693c922Shikaru 		POW_TAG_OP_SWTAG_FULL,	/* op == SWTAG_FULL */
208f693c922Shikaru 		0,			/* qos (not used for SWTAG_FULL) */
209f693c922Shikaru 		grp,
210f693c922Shikaru 		type,
211f693c922Shikaru 		tag);
212f693c922Shikaru }
213f693c922Shikaru 
214f693c922Shikaru /* SWTAG_DESCHED */
215f693c922Shikaru 
21687fd18f8Schristos static __inline void
octpow_ops_swtag_desched(int no_sched,int grp,int type,uint32_t tag)2173f508e4dSsimonb octpow_ops_swtag_desched(int no_sched, int grp, int type, uint32_t tag)
218f693c922Shikaru {
219b9fcd28bSsimonb 
2203f508e4dSsimonb 	octpow_store(
221b9fcd28bSsimonb 		POW_STORE_SUBDID_DESCHED,
222f693c922Shikaru 		0,			/* addr (not used for SWTAG_DESCHED) */
223f693c922Shikaru 		no_sched,
224f693c922Shikaru 		0,			/* index (not used for SWTAG_DESCHED) */
225f693c922Shikaru 		POW_TAG_OP_SWTAG_DESCHED, /* op == SWTAG_DESCHED */
226f693c922Shikaru 		0,			/* qos (not used for SWTAG_DESCHED) */
227f693c922Shikaru 		grp,
228f693c922Shikaru 		type,
229f693c922Shikaru 		tag);
230f693c922Shikaru }
231f693c922Shikaru 
232f693c922Shikaru /* DESCHED */
233f693c922Shikaru 
23487fd18f8Schristos static __inline void
octpow_ops_desched(int no_sched)2353f508e4dSsimonb octpow_ops_desched(int no_sched)
236f693c922Shikaru {
237b9fcd28bSsimonb 
2383f508e4dSsimonb 	octpow_store(
239b9fcd28bSsimonb 		POW_STORE_SUBDID_DESCHED,
240f693c922Shikaru 		0,			/* addr (not used for DESCHED) */
241f693c922Shikaru 		no_sched,
242f693c922Shikaru 		0,			/* index (not used for DESCHED) */
243f693c922Shikaru 		POW_TAG_OP_DESCHED,	/* op == DESCHED */
244f693c922Shikaru 		0,			/* qos (not used for DESCHED) */
245f693c922Shikaru 		0,			/* grp (not used for DESCHED) */
246f693c922Shikaru 		0,			/* type (not used for DESCHED) */
247f693c922Shikaru 		0);			/* tag (not used for DESCHED) */
248f693c922Shikaru }
249f693c922Shikaru 
250f693c922Shikaru /* ADDWQ */
251f693c922Shikaru 
25287fd18f8Schristos static __inline void
octpow_ops_addwq(paddr_t addr,int qos,int grp,int type,uint32_t tag)2533f508e4dSsimonb octpow_ops_addwq(paddr_t addr, int qos, int grp, int type, uint32_t tag)
254f693c922Shikaru {
255b9fcd28bSsimonb 
2563f508e4dSsimonb 	octpow_store(
257b9fcd28bSsimonb 		POW_STORE_SUBDID_OTHER,
258f693c922Shikaru 		addr,
259f693c922Shikaru 		0,			/* no_sched (not used for ADDWQ) */
260f693c922Shikaru 		0,			/* index (not used for ADDWQ) */
261f693c922Shikaru 		POW_TAG_OP_ADDWQ,	/* op == ADDWQ */
262f693c922Shikaru 		qos,
263f693c922Shikaru 		grp,
264f693c922Shikaru 		type,
265f693c922Shikaru 		tag);
266f693c922Shikaru }
267f693c922Shikaru 
268f693c922Shikaru /* UPD_WQP_GRP */
269f693c922Shikaru 
27087fd18f8Schristos static __inline void
octpow_ops_upd_wqp_grp(paddr_t addr,int grp)2713f508e4dSsimonb octpow_ops_upd_wqp_grp(paddr_t addr, int grp)
272f693c922Shikaru {
273b9fcd28bSsimonb 
2743f508e4dSsimonb 	octpow_store(
275b9fcd28bSsimonb 		POW_STORE_SUBDID_OTHER,
276f693c922Shikaru 		addr,
277f693c922Shikaru 		0,			/* no_sched (not used for UPD_WQP_GRP) */
278f693c922Shikaru 		0,			/* index (not used for UPD_WQP_GRP) */
279f693c922Shikaru 		POW_TAG_OP_UPD_WQP_GRP,	/* op == UPD_WQP_GRP */
280f693c922Shikaru 		0,			/* qos (not used for UPD_WQP_GRP) */
281f693c922Shikaru 		grp,
282f693c922Shikaru 		0,			/* type (not used for UPD_WQP_GRP) */
283f693c922Shikaru 		0);			/* tag (not used for UPD_WQP_GRP) */
284f693c922Shikaru }
285f693c922Shikaru 
286f693c922Shikaru /* CLR_NSCHED */
287f693c922Shikaru 
28887fd18f8Schristos static __inline void
octpow_ops_clr_nsched(paddr_t addr,int index)2893f508e4dSsimonb octpow_ops_clr_nsched(paddr_t addr, int index)
290f693c922Shikaru {
291b9fcd28bSsimonb 
2923f508e4dSsimonb 	octpow_store(
293b9fcd28bSsimonb 		POW_STORE_SUBDID_OTHER,
294f693c922Shikaru 		addr,
295f693c922Shikaru 		0,			/* no_sched (not used for CLR_NSCHED) */
296f693c922Shikaru 		index,
297f693c922Shikaru 		POW_TAG_OP_CLR_NSCHED,	/* op == CLR_NSCHED */
298f693c922Shikaru 		0,			/* qos (not used for CLR_NSCHED) */
299f693c922Shikaru 		0,			/* grp (not used for CLR_NSCHED) */
300f693c922Shikaru 		0,			/* type (not used for CLR_NSCHED) */
301f693c922Shikaru 		0);			/* tag (not used for CLR_NSCHED) */
302f693c922Shikaru }
303f693c922Shikaru 
304f693c922Shikaru /* NOP */
305f693c922Shikaru 
30687fd18f8Schristos static __inline void
octpow_ops_nop(void)3073f508e4dSsimonb octpow_ops_nop(void)
308f693c922Shikaru {
309b9fcd28bSsimonb 
3103f508e4dSsimonb 	octpow_store(
311b9fcd28bSsimonb 		POW_STORE_SUBDID_OTHER,
312f693c922Shikaru 		0,			/* addr (not used for NOP) */
313f693c922Shikaru 		0,			/* no_sched (not used for NOP) */
314f693c922Shikaru 		0,			/* index (not used for NOP) */
315f693c922Shikaru 		POW_TAG_OP_NOP,		/* op == NOP */
316f693c922Shikaru 		0,			/* qos (not used for NOP) */
317f693c922Shikaru 		0,			/* grp (not used for NOP) */
318f693c922Shikaru 		0,			/* type (not used for NOP) */
319f693c922Shikaru 		0);			/* tag (not used for NOP) */
320f693c922Shikaru }
321f693c922Shikaru 
322*7cfbdc5bSsimonb /*
323*7cfbdc5bSsimonb  * Check if there is a pending POW tag switch.
324*7cfbdc5bSsimonb  */
325*7cfbdc5bSsimonb static __inline int
octpow_tag_sw_pending(void)326*7cfbdc5bSsimonb octpow_tag_sw_pending(void)
327*7cfbdc5bSsimonb {
328*7cfbdc5bSsimonb 	int result;
329*7cfbdc5bSsimonb 
330*7cfbdc5bSsimonb 	/*
331*7cfbdc5bSsimonb 	 * "RDHWR rt, $30" returns:
332*7cfbdc5bSsimonb 	 *	0 => pending bit is set
333*7cfbdc5bSsimonb 	 *	1 => pending bit is clear
334*7cfbdc5bSsimonb 	 */
335*7cfbdc5bSsimonb 
336*7cfbdc5bSsimonb 	__asm volatile (
337*7cfbdc5bSsimonb 		"	.set	push\n"
338*7cfbdc5bSsimonb 		"	.set	noreorder\n"
339*7cfbdc5bSsimonb 		"	.set	arch=mips64r2\n"
340*7cfbdc5bSsimonb 		"	rdhwr	%0, $30\n"
341*7cfbdc5bSsimonb 		"	.set	pop\n"
342*7cfbdc5bSsimonb 		: "=r" (result));
343*7cfbdc5bSsimonb 	return result == 0;
344*7cfbdc5bSsimonb }
345*7cfbdc5bSsimonb 
346*7cfbdc5bSsimonb /*
347*7cfbdc5bSsimonb  * Wait until there is no pending POW tag switch.
348*7cfbdc5bSsimonb  */
349*7cfbdc5bSsimonb static inline void
octpow_tag_sw_wait(void)350*7cfbdc5bSsimonb octpow_tag_sw_wait(void)
351*7cfbdc5bSsimonb {
352*7cfbdc5bSsimonb 	while (octpow_tag_sw_pending())
353*7cfbdc5bSsimonb 		continue;
354*7cfbdc5bSsimonb }
355*7cfbdc5bSsimonb 
356f693c922Shikaru /* -------------------------------------------------------------------------- */
357f693c922Shikaru 
358f693c922Shikaru /*
359f693c922Shikaru  * global functions
360f693c922Shikaru  */
36187fd18f8Schristos static __inline void
octpow_work_request_async(uint64_t scraddr,uint64_t wait)3623f508e4dSsimonb octpow_work_request_async(uint64_t scraddr, uint64_t wait)
363f693c922Shikaru {
364b9fcd28bSsimonb 
3653f508e4dSsimonb         octpow_ops_get_work_iobdma(scraddr, wait);
366f693c922Shikaru }
367f693c922Shikaru 
36887fd18f8Schristos static __inline uint64_t *
octpow_work_response_async(uint64_t scraddr)3693f508e4dSsimonb octpow_work_response_async(uint64_t scraddr)
370f693c922Shikaru {
371f693c922Shikaru 	uint64_t result;
372f693c922Shikaru 
373f693c922Shikaru 	OCTEON_SYNCIOBDMA;
374f693c922Shikaru 	result = octeon_cvmseg_read_8(scraddr);
375f693c922Shikaru 
376d7e78fcfSmatt 	paddr_t addr = result & POW_IOBDMA_GET_WORK_RESULT_ADDR;
377d7e78fcfSmatt 
378d7e78fcfSmatt 	if (result & POW_IOBDMA_GET_WORK_RESULT_NO_WORK)
379d7e78fcfSmatt 	    return NULL;
380d7e78fcfSmatt #ifdef __mips_n32
381d7e78fcfSmatt 	KASSERT(addr < MIPS_PHYS_MASK);
382d7e78fcfSmatt 	return (uint64_t *)MIPS_PHYS_TO_KSEG0(addr);
383d7e78fcfSmatt #else
384d7e78fcfSmatt 	return (uint64_t *)MIPS_PHYS_TO_XKPHYS_CACHED(addr);
385d7e78fcfSmatt #endif
386f693c922Shikaru }
387f693c922Shikaru 
38887fd18f8Schristos static __inline void
octpow_config_int_pc(struct octpow_softc * sc,int unit)3893f508e4dSsimonb octpow_config_int_pc(struct octpow_softc *sc, int unit)
390f693c922Shikaru {
391f693c922Shikaru 	uint64_t wq_int_pc;
392f693c922Shikaru 	uint64_t pc_thr;
393f693c922Shikaru 	static uint64_t cpu_clock_hz;
394f693c922Shikaru 
395f693c922Shikaru 	if (cpu_clock_hz == 0)
396f693c922Shikaru 		cpu_clock_hz  = curcpu()->ci_cpu_freq;
397f693c922Shikaru 
398f693c922Shikaru 	/* from SDK */
399f693c922Shikaru 	pc_thr = (cpu_clock_hz) / (unit * 16 * 256);
400f693c922Shikaru 
401b9fcd28bSsimonb 	wq_int_pc = __SHIFTIN(pc_thr, POW_WQ_INT_PC_PC_THR);
402f693c922Shikaru 	_POW_WR8(sc, POW_WQ_INT_PC_OFFSET, wq_int_pc);
403f693c922Shikaru }
404f693c922Shikaru 
40587fd18f8Schristos static __inline void
octpow_config_int_pc_rate(struct octpow_softc * sc,int rate)4063f508e4dSsimonb octpow_config_int_pc_rate(struct octpow_softc *sc, int rate)
407f693c922Shikaru {
408b9fcd28bSsimonb 
4093f508e4dSsimonb 	octpow_config_int_pc(sc, sc->sc_int_pc_base / rate);
410f693c922Shikaru }
411f693c922Shikaru 
412*7cfbdc5bSsimonb #endif /* !_OCTEON_POWVAR_H_ */
413