xref: /openbsd/sys/arch/octeon/dev/cn30xxpow.c (revision 52334306)
1*52334306Syasuoka /*	$OpenBSD: cn30xxpow.c,v 1.17 2022/12/28 01:39:21 yasuoka Exp $	*/
24a04f2fdSsyuu 
34a04f2fdSsyuu /*
44a04f2fdSsyuu  * Copyright (c) 2007 Internet Initiative Japan, Inc.
54a04f2fdSsyuu  * All rights reserved.
64a04f2fdSsyuu  *
74a04f2fdSsyuu  * Redistribution and use in source and binary forms, with or without
84a04f2fdSsyuu  * modification, are permitted provided that the following conditions
94a04f2fdSsyuu  * are met:
104a04f2fdSsyuu  * 1. Redistributions of source code must retain the above copyright
114a04f2fdSsyuu  *    notice, this list of conditions and the following disclaimer.
124a04f2fdSsyuu  * 2. Redistributions in binary form must reproduce the above copyright
134a04f2fdSsyuu  *    notice, this list of conditions and the following disclaimer in the
144a04f2fdSsyuu  *    documentation and/or other materials provided with the distribution.
154a04f2fdSsyuu  *
16*52334306Syasuoka  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
174a04f2fdSsyuu  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
184a04f2fdSsyuu  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*52334306Syasuoka  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
204a04f2fdSsyuu  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
214a04f2fdSsyuu  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
224a04f2fdSsyuu  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
234a04f2fdSsyuu  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
244a04f2fdSsyuu  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
254a04f2fdSsyuu  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
264a04f2fdSsyuu  * SUCH DAMAGE.
274a04f2fdSsyuu  */
284a04f2fdSsyuu 
294a04f2fdSsyuu #include <sys/param.h>
304a04f2fdSsyuu #include <sys/systm.h>
314a04f2fdSsyuu 
324a04f2fdSsyuu #include <machine/bus.h>
334a04f2fdSsyuu #include <machine/octeonvar.h>
344a04f2fdSsyuu 
354a04f2fdSsyuu #include <octeon/dev/iobusvar.h>
364a04f2fdSsyuu #include <octeon/dev/cn30xxpowreg.h>
374a04f2fdSsyuu #include <octeon/dev/cn30xxpowvar.h>
384a04f2fdSsyuu 
394a04f2fdSsyuu void	cn30xxpow_bootstrap(struct octeon_config *);
404a04f2fdSsyuu 
4134a927e5Smiod void	cn30xxpow_init(struct cn30xxpow_softc *);
4234a927e5Smiod void	cn30xxpow_init_regs(struct cn30xxpow_softc *);
4334a927e5Smiod void	cn30xxpow_config_int(struct cn30xxpow_softc *, int,
444a04f2fdSsyuu 	    uint64_t, uint64_t, uint64_t);
454a04f2fdSsyuu 
464a04f2fdSsyuu struct cn30xxpow_softc	cn30xxpow_softc;
474a04f2fdSsyuu 
484a04f2fdSsyuu /* -------------------------------------------------------------------------- */
494a04f2fdSsyuu 
504a04f2fdSsyuu /* ---- operation primitive functions */
514a04f2fdSsyuu 
524a04f2fdSsyuu /* 5.11.1 Load Operations */
534a04f2fdSsyuu 
544a04f2fdSsyuu /* 5.11.2 IOBDMA Operations */
554a04f2fdSsyuu 
564a04f2fdSsyuu /* 5.11.3 Store Operations */
574a04f2fdSsyuu 
584a04f2fdSsyuu /* -------------------------------------------------------------------------- */
594a04f2fdSsyuu 
604a04f2fdSsyuu /* ---- utility functions */
614a04f2fdSsyuu 
624a04f2fdSsyuu void
cn30xxpow_work_request_async(uint64_t scraddr,uint64_t wait)634a04f2fdSsyuu cn30xxpow_work_request_async(uint64_t scraddr, uint64_t wait)
644a04f2fdSsyuu {
654a04f2fdSsyuu         cn30xxpow_ops_get_work_iobdma(scraddr, wait);
664a04f2fdSsyuu }
674a04f2fdSsyuu 
684a04f2fdSsyuu uint64_t *
cn30xxpow_work_response_async(uint64_t scraddr)694a04f2fdSsyuu cn30xxpow_work_response_async(uint64_t scraddr)
704a04f2fdSsyuu {
714a04f2fdSsyuu 	uint64_t result;
724a04f2fdSsyuu 
7390de25d4Svisa 	octeon_synciobdma();
744a04f2fdSsyuu 	result = octeon_cvmseg_read_8(scraddr);
754a04f2fdSsyuu 
764a04f2fdSsyuu 	return (result & POW_IOBDMA_GET_WORK_RESULT_NO_WORK) ?
774a04f2fdSsyuu 	    NULL :
78706011a1Smiod 	    (uint64_t *)PHYS_TO_XKPHYS(
79706011a1Smiod 		result & POW_IOBDMA_GET_WORK_RESULT_ADDR, CCA_CACHED);
804a04f2fdSsyuu }
814a04f2fdSsyuu 
824a04f2fdSsyuu /* -------------------------------------------------------------------------- */
834a04f2fdSsyuu 
844a04f2fdSsyuu /* ---- initialization and configuration */
854a04f2fdSsyuu 
864a04f2fdSsyuu void
cn30xxpow_bootstrap(struct octeon_config * mcp)874a04f2fdSsyuu cn30xxpow_bootstrap(struct octeon_config *mcp)
884a04f2fdSsyuu {
894a04f2fdSsyuu 	struct cn30xxpow_softc *sc = &cn30xxpow_softc;
904a04f2fdSsyuu 
914a04f2fdSsyuu 	sc->sc_regt = mcp->mc_iobus_bust;
924a04f2fdSsyuu 	/* XXX */
934a04f2fdSsyuu 
944a04f2fdSsyuu 	cn30xxpow_init(sc);
954a04f2fdSsyuu }
964a04f2fdSsyuu 
9734a927e5Smiod void
cn30xxpow_config_int(struct cn30xxpow_softc * sc,int group,uint64_t tc_thr,uint64_t ds_thr,uint64_t iq_thr)984a04f2fdSsyuu cn30xxpow_config_int(struct cn30xxpow_softc *sc, int group,
994a04f2fdSsyuu    uint64_t tc_thr, uint64_t ds_thr, uint64_t iq_thr)
1004a04f2fdSsyuu {
1014a04f2fdSsyuu 	uint64_t wq_int_thr;
1024a04f2fdSsyuu 
1034a04f2fdSsyuu 	wq_int_thr =
1044a04f2fdSsyuu 	    POW_WQ_INT_THRX_TC_EN |
1054a04f2fdSsyuu 	    (tc_thr << POW_WQ_INT_THRX_TC_THR_SHIFT) |
1064a04f2fdSsyuu 	    (ds_thr << POW_WQ_INT_THRX_DS_THR_SHIFT) |
1074a04f2fdSsyuu 	    (iq_thr << POW_WQ_INT_THRX_IQ_THR_SHIFT);
1084a04f2fdSsyuu 	_POW_WR8(sc, POW_WQ_INT_THR0_OFFSET + (group * 8), wq_int_thr);
1094a04f2fdSsyuu }
1104a04f2fdSsyuu 
1114a04f2fdSsyuu /*
1124a04f2fdSsyuu  * interrupt threshold configuration
1134a04f2fdSsyuu  *
1144a04f2fdSsyuu  * => DS / IQ
1154a04f2fdSsyuu  *    => ...
1164a04f2fdSsyuu  * => time counter threshold
1174a04f2fdSsyuu  *    => unit is 1msec
1184a04f2fdSsyuu  *    => each group can set timeout
1194a04f2fdSsyuu  * => temporary disable bit
1204a04f2fdSsyuu  *    => use CIU generic timer
1214a04f2fdSsyuu  */
1224a04f2fdSsyuu 
1234a04f2fdSsyuu void
cn30xxpow_config(struct cn30xxpow_softc * sc,int group)1244a04f2fdSsyuu cn30xxpow_config(struct cn30xxpow_softc *sc, int group)
1254a04f2fdSsyuu {
1264a04f2fdSsyuu 
1274a04f2fdSsyuu 	cn30xxpow_config_int(sc, group,
1284a04f2fdSsyuu 	    0x0f,		/* TC */
1294a04f2fdSsyuu 	    0x00,		/* DS */
1304a04f2fdSsyuu 	    0x00);		/* IQ */
1314a04f2fdSsyuu }
1324a04f2fdSsyuu 
1334a04f2fdSsyuu void
cn30xxpow_init(struct cn30xxpow_softc * sc)1344a04f2fdSsyuu cn30xxpow_init(struct cn30xxpow_softc *sc)
1354a04f2fdSsyuu {
1364a04f2fdSsyuu 	cn30xxpow_init_regs(sc);
1374a04f2fdSsyuu 
1384a04f2fdSsyuu 	sc->sc_int_pc_base = 10000;
1394a04f2fdSsyuu 	cn30xxpow_config_int_pc(sc, sc->sc_int_pc_base);
1404a04f2fdSsyuu }
1414a04f2fdSsyuu 
1424a04f2fdSsyuu void
cn30xxpow_init_regs(struct cn30xxpow_softc * sc)1434a04f2fdSsyuu cn30xxpow_init_regs(struct cn30xxpow_softc *sc)
1444a04f2fdSsyuu {
1454a04f2fdSsyuu 	int status;
1464a04f2fdSsyuu 
1474a04f2fdSsyuu 	status = bus_space_map(sc->sc_regt, POW_BASE, POW_SIZE, 0,
1484a04f2fdSsyuu 	    &sc->sc_regh);
1494a04f2fdSsyuu 	if (status != 0)
1504a04f2fdSsyuu 		panic("can't map %s space", "pow register");
1514a04f2fdSsyuu }
152