1*52334306Syasuoka /* $OpenBSD: cn30xxpowvar.h,v 1.6 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 #ifndef _CN30XXPOWVAR_H_ 304a04f2fdSsyuu #define _CN30XXPOWVAR_H_ 314a04f2fdSsyuu 324a04f2fdSsyuu #define POW_TAG_TYPE_ORDERED 0 334a04f2fdSsyuu #define POW_TAG_TYPE_ATOMIC 1 344a04f2fdSsyuu #define POW_TAG_TYPE_NULL 2 354a04f2fdSsyuu #define POW_TAG_TYPE_NULL_NULL 3 364a04f2fdSsyuu 374a04f2fdSsyuu #define POW_TAG_OP_SWTAG 0 384a04f2fdSsyuu #define POW_TAG_OP_SWTAG_FULL 1 394a04f2fdSsyuu #define POW_TAG_OP_SWTAG_DESCHED 2 404a04f2fdSsyuu #define POW_TAG_OP_DESCHED 3 414a04f2fdSsyuu #define POW_TAG_OP_ADDWQ 4 424a04f2fdSsyuu #define POW_TAG_OP_UPD_WQP_GRP 5 434a04f2fdSsyuu #define POW_TAG_OP_CLR_NSCHED 7 444a04f2fdSsyuu #define POW_TAG_OP_NOP 15 454a04f2fdSsyuu 464a04f2fdSsyuu #define POW_WAIT 1 474a04f2fdSsyuu #define POW_NO_WAIT 0 484a04f2fdSsyuu 494e19228dSvisa #define POW_WORKQ_IRQ(group) (group) 504e19228dSvisa 514a04f2fdSsyuu /* XXX */ 524a04f2fdSsyuu struct cn30xxpow_softc { 534a04f2fdSsyuu struct device sc_dev; 544a04f2fdSsyuu bus_space_tag_t sc_regt; 554a04f2fdSsyuu bus_space_handle_t sc_regh; 564a04f2fdSsyuu int sc_port; 574a04f2fdSsyuu int sc_int_pc_base; 584a04f2fdSsyuu }; 594a04f2fdSsyuu 604a04f2fdSsyuu /* XXX */ 614a04f2fdSsyuu struct cn30xxpow_attach_args { 624a04f2fdSsyuu int aa_port; 634a04f2fdSsyuu bus_space_tag_t aa_regt; 644a04f2fdSsyuu }; 654a04f2fdSsyuu 664a04f2fdSsyuu void cn30xxpow_config(struct cn30xxpow_softc *, int); 674a04f2fdSsyuu 684a04f2fdSsyuu #define _POW_RD8(sc, off) \ 694a04f2fdSsyuu bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, (off)) 704a04f2fdSsyuu #define _POW_WR8(sc, off, v) \ 714a04f2fdSsyuu bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, (off), (v)) 724a04f2fdSsyuu #define _POW_GROUP_RD8(sc, pi, off) \ 734a04f2fdSsyuu bus_space_read_8((sc)->sc_regt, (sc)->sc_regh, \ 744a04f2fdSsyuu (off) + sizeof(uint64_t) * (pi)->pi_group) 754a04f2fdSsyuu #define _POW_GROUP_WR8(sc, pi, off, v) \ 764a04f2fdSsyuu bus_space_write_8((sc)->sc_regt, (sc)->sc_regh, \ 774a04f2fdSsyuu (off) + sizeof(uint64_t) * (pi)->pi_group, (v)) 784a04f2fdSsyuu 794a04f2fdSsyuu extern struct cn30xxpow_softc cn30xxpow_softc; 804a04f2fdSsyuu 814a04f2fdSsyuu /* -------------------------------------------------------------------------- */ 824a04f2fdSsyuu 834a04f2fdSsyuu /* 5.11.1 Load Operations */ 844a04f2fdSsyuu 854a04f2fdSsyuu /* GET_WORK Loads */ 864a04f2fdSsyuu 874a04f2fdSsyuu static inline uint64_t 884a04f2fdSsyuu cn30xxpow_ops_get_work_load( 894a04f2fdSsyuu int wait) /* 0-1 */ 904a04f2fdSsyuu { 914a04f2fdSsyuu uint64_t ptr = 924a04f2fdSsyuu POW_OPERATION_BASE_IO_BIT | 934a04f2fdSsyuu __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) | 944a04f2fdSsyuu __BITS64_SET(POW_OPERATION_BASE_SUB_DID, 0x00) | 954a04f2fdSsyuu __BITS64_SET(POW_GET_WORK_LOAD_WAIT, wait); 964a04f2fdSsyuu 974a04f2fdSsyuu return octeon_xkphys_read_8(ptr); 984a04f2fdSsyuu } 994a04f2fdSsyuu 1004a04f2fdSsyuu /* 5.11.2 IOBDMA Operations */ 1014a04f2fdSsyuu 1024a04f2fdSsyuu /* 1034a04f2fdSsyuu * XXXSEIL 1044a04f2fdSsyuu * ``subdid'' values are inverted between ``get_work_addr'' and ``null_read_id'' 1054a04f2fdSsyuu * in CN30XX-HM-1.0 and CN31XX-HM-1.01. (Corrected in CN50XX-HM-0.99A.) 1064a04f2fdSsyuu * 1074a04f2fdSsyuu * XXXSEIL 1084a04f2fdSsyuu * The ``scraddr'' part is index in 8 byte words, not address. This is not 1094a04f2fdSsyuu * documented... 1104a04f2fdSsyuu */ 1114a04f2fdSsyuu 1124a04f2fdSsyuu /* GET_WORK IOBDMAs */ 1134a04f2fdSsyuu 1144a04f2fdSsyuu static inline void 1154a04f2fdSsyuu cn30xxpow_ops_get_work_iobdma( 1164a04f2fdSsyuu int scraddr, /* 0-2047 */ 1174a04f2fdSsyuu int wait) /* 0-1 */ 1184a04f2fdSsyuu { 1194a04f2fdSsyuu /* ``scraddr'' part is index in 64-bit words, not address */ 1204a04f2fdSsyuu const int scrindex = scraddr / sizeof(uint64_t); 1214a04f2fdSsyuu 1224a04f2fdSsyuu uint64_t args = 1234a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_GET_WORK_WAIT, wait); 1244a04f2fdSsyuu uint64_t value = 1254a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_BASE_SCRADDR, scrindex) | 1264a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_BASE_LEN, 0x01) | 1274a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_BASE_MAJOR_DID, 0x0c) | 1284a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_BASE_SUB_DID, 0x00) | 1294a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_BASE_39_0, args); 1304a04f2fdSsyuu 1314a04f2fdSsyuu octeon_iobdma_write_8(value); 1324a04f2fdSsyuu } 1334a04f2fdSsyuu 1344a04f2fdSsyuu /* NULL_RD IOBDMAs */ 1354a04f2fdSsyuu 1364a04f2fdSsyuu static inline void 1374a04f2fdSsyuu cn30xxpow_ops_null_rd_iobdma( 1384a04f2fdSsyuu int scraddr) /* 0-2047 */ 1394a04f2fdSsyuu { 1404a04f2fdSsyuu /* ``scraddr'' part is index in 64-bit words, not address */ 1414a04f2fdSsyuu const int scrindex = scraddr / sizeof(uint64_t); 1424a04f2fdSsyuu 1434a04f2fdSsyuu uint64_t value = 1444a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_BASE_SCRADDR, scrindex) | 1454a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_BASE_LEN, 0x01) | 1464a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_BASE_MAJOR_DID, 0x0c) | 1474a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_BASE_SUB_DID, 0x04) | 1484a04f2fdSsyuu __BITS64_SET(POW_IOBDMA_BASE_39_0, 0); 1494a04f2fdSsyuu 1504a04f2fdSsyuu octeon_iobdma_write_8(value); 1514a04f2fdSsyuu } 1524a04f2fdSsyuu 1534a04f2fdSsyuu /* 5.11.3 Store Operations */ 1544a04f2fdSsyuu 1554a04f2fdSsyuu static inline void 1564a04f2fdSsyuu cn30xxpow_store( 1574a04f2fdSsyuu int subdid, /* 0, 1, 3 */ 1584a04f2fdSsyuu uint64_t addr, /* 0-0x0000.000f.ffff.ffff */ 1594a04f2fdSsyuu int no_sched, /* 0, 1 */ 1604a04f2fdSsyuu int index, /* 0-8191 */ 1614a04f2fdSsyuu int op, /* 0-15 */ 1624a04f2fdSsyuu int qos, /* 0-7 */ 1634a04f2fdSsyuu int grp, /* 0-7 */ 1644a04f2fdSsyuu int type, /* 0-7 */ 1654a04f2fdSsyuu uint32_t tag) /* 0-0xffff.ffff */ 1664a04f2fdSsyuu { 1674a04f2fdSsyuu /* Physical Address to Store to POW */ 1684a04f2fdSsyuu uint64_t ptr = 1694a04f2fdSsyuu POW_OPERATION_BASE_IO_BIT | 1704a04f2fdSsyuu __BITS64_SET(POW_OPERATION_BASE_MAJOR_DID, 0x0c) | 1714a04f2fdSsyuu __BITS64_SET(POW_OPERATION_BASE_SUB_DID, subdid) | 1724a04f2fdSsyuu __BITS64_SET(POW_PHY_ADDR_STORE_ADDR, addr); 1734a04f2fdSsyuu 1744a04f2fdSsyuu /* Store Data on Store to POW */ 1754a04f2fdSsyuu uint64_t args = 1764a04f2fdSsyuu __BITS64_SET(POW_STORE_DATA_NO_SCHED, no_sched) | 1774a04f2fdSsyuu __BITS64_SET(POW_STORE_DATA_INDEX, index) | 1784a04f2fdSsyuu __BITS64_SET(POW_STORE_DATA_OP, op) | 1794a04f2fdSsyuu __BITS64_SET(POW_STORE_DATA_QOS, qos) | 1804a04f2fdSsyuu __BITS64_SET(POW_STORE_DATA_GRP, grp) | 1814a04f2fdSsyuu __BITS64_SET(POW_STORE_DATA_TYPE, type) | 1824a04f2fdSsyuu __BITS64_SET(POW_STORE_DATA_TAG, tag); 1834a04f2fdSsyuu 1844a04f2fdSsyuu octeon_xkphys_write_8(ptr, args); 1854a04f2fdSsyuu } 1864a04f2fdSsyuu 1874a04f2fdSsyuu /* SWTAG */ 1884a04f2fdSsyuu 1894a04f2fdSsyuu static inline void 1904a04f2fdSsyuu cn30xxpow_ops_swtag(int type, uint32_t tag) 1914a04f2fdSsyuu { 1924a04f2fdSsyuu cn30xxpow_store( 1934a04f2fdSsyuu 1, /* subdid == 1 */ 1944a04f2fdSsyuu 0, /* addr (not used for SWTAG) */ 1954a04f2fdSsyuu 0, /* no_sched (not used for SWTAG) */ 1964a04f2fdSsyuu 0, /* index (not used for SWTAG) */ 1974a04f2fdSsyuu POW_TAG_OP_SWTAG, /* op == SWTAG */ 1984a04f2fdSsyuu 0, /* qos (not used for SWTAG) */ 1994a04f2fdSsyuu 0, /* grp (not used for SWTAG) */ 2004a04f2fdSsyuu type, 2014a04f2fdSsyuu tag); 2024a04f2fdSsyuu /* switch to NULL completes immediately */ 2034a04f2fdSsyuu } 2044a04f2fdSsyuu 2054a04f2fdSsyuu /* SWTAG_FULL */ 2064a04f2fdSsyuu 2074a04f2fdSsyuu static inline void 2084a04f2fdSsyuu cn30xxpow_ops_swtag_full(paddr_t addr, int grp, int type, uint32_t tag) 2094a04f2fdSsyuu { 2104a04f2fdSsyuu cn30xxpow_store( 2114a04f2fdSsyuu 0, /* subdid == 0 */ 2124a04f2fdSsyuu addr, 2134a04f2fdSsyuu 0, /* no_sched (not used for SWTAG_FULL) */ 2144a04f2fdSsyuu 0, /* index (not used for SWTAG_FULL) */ 2154a04f2fdSsyuu POW_TAG_OP_SWTAG_FULL, /* op == SWTAG_FULL */ 2164a04f2fdSsyuu 0, /* qos (not used for SWTAG_FULL) */ 2174a04f2fdSsyuu grp, 2184a04f2fdSsyuu type, 2194a04f2fdSsyuu tag); 2204a04f2fdSsyuu } 2214a04f2fdSsyuu 2224a04f2fdSsyuu /* SWTAG_DESCHED */ 2234a04f2fdSsyuu 2244a04f2fdSsyuu static inline void 2254a04f2fdSsyuu cn30xxpow_ops_swtag_desched(int no_sched, int grp, int type, uint32_t tag) 2264a04f2fdSsyuu { 2274a04f2fdSsyuu cn30xxpow_store( 2284a04f2fdSsyuu 3, /* subdid == 3 */ 2294a04f2fdSsyuu 0, /* addr (not used for SWTAG_DESCHED) */ 2304a04f2fdSsyuu no_sched, 2314a04f2fdSsyuu 0, /* index (not used for SWTAG_DESCHED) */ 2324a04f2fdSsyuu POW_TAG_OP_SWTAG_DESCHED, /* op == SWTAG_DESCHED */ 2334a04f2fdSsyuu 0, /* qos (not used for SWTAG_DESCHED) */ 2344a04f2fdSsyuu grp, 2354a04f2fdSsyuu type, 2364a04f2fdSsyuu tag); 2374a04f2fdSsyuu } 2384a04f2fdSsyuu 2394a04f2fdSsyuu /* DESCHED */ 2404a04f2fdSsyuu 2414a04f2fdSsyuu static inline void 2424a04f2fdSsyuu cn30xxpow_ops_desched(int no_sched) 2434a04f2fdSsyuu { 2444a04f2fdSsyuu cn30xxpow_store( 2454a04f2fdSsyuu 3, /* subdid == 3 */ 2464a04f2fdSsyuu 0, /* addr (not used for DESCHED) */ 2474a04f2fdSsyuu no_sched, 2484a04f2fdSsyuu 0, /* index (not used for DESCHED) */ 2494a04f2fdSsyuu POW_TAG_OP_DESCHED, /* op == DESCHED */ 2504a04f2fdSsyuu 0, /* qos (not used for DESCHED) */ 2514a04f2fdSsyuu 0, /* grp (not used for DESCHED) */ 2524a04f2fdSsyuu 0, /* type (not used for DESCHED) */ 2534a04f2fdSsyuu 0); /* tag (not used for DESCHED) */ 2544a04f2fdSsyuu } 2554a04f2fdSsyuu 2564a04f2fdSsyuu /* ADDWQ */ 2574a04f2fdSsyuu 2584a04f2fdSsyuu static inline void 2594a04f2fdSsyuu cn30xxpow_ops_addwq(paddr_t addr, int qos, int grp, int type, uint32_t tag) 2604a04f2fdSsyuu { 2614a04f2fdSsyuu cn30xxpow_store( 2624a04f2fdSsyuu 1, /* subdid == 1 */ 2634a04f2fdSsyuu addr, 2644a04f2fdSsyuu 0, /* no_sched (not used for ADDWQ) */ 2654a04f2fdSsyuu 0, /* index (not used for ADDWQ) */ 2664a04f2fdSsyuu POW_TAG_OP_ADDWQ, /* op == ADDWQ */ 2674a04f2fdSsyuu qos, 2684a04f2fdSsyuu grp, 2694a04f2fdSsyuu type, 2704a04f2fdSsyuu tag); 2714a04f2fdSsyuu } 2724a04f2fdSsyuu 2734a04f2fdSsyuu /* UPD_WQP_GRP */ 2744a04f2fdSsyuu 2754a04f2fdSsyuu static inline void 2764a04f2fdSsyuu cn30xxpow_ops_upd_wqp_grp(paddr_t addr, int grp) 2774a04f2fdSsyuu { 2784a04f2fdSsyuu cn30xxpow_store( 2794a04f2fdSsyuu 1, /* subdid == 1 */ 2804a04f2fdSsyuu addr, 2814a04f2fdSsyuu 0, /* no_sched (not used for UPD_WQP_GRP) */ 2824a04f2fdSsyuu 0, /* index (not used for UPD_WQP_GRP) */ 2834a04f2fdSsyuu POW_TAG_OP_UPD_WQP_GRP, /* op == UPD_WQP_GRP */ 2844a04f2fdSsyuu 0, /* qos (not used for UPD_WQP_GRP) */ 2854a04f2fdSsyuu grp, 2864a04f2fdSsyuu 0, /* type (not used for UPD_WQP_GRP) */ 2874a04f2fdSsyuu 0); /* tag (not used for UPD_WQP_GRP) */ 2884a04f2fdSsyuu } 2894a04f2fdSsyuu 2904a04f2fdSsyuu /* CLR_NSCHED */ 2914a04f2fdSsyuu 2924a04f2fdSsyuu static inline void 2934a04f2fdSsyuu cn30xxpow_ops_clr_nsched(paddr_t addr, int index) 2944a04f2fdSsyuu { 2954a04f2fdSsyuu cn30xxpow_store( 2964a04f2fdSsyuu 1, /* subdid == 1 */ 2974a04f2fdSsyuu addr, 2984a04f2fdSsyuu 0, /* no_sched (not used for CLR_NSCHED) */ 2994a04f2fdSsyuu index, 3004a04f2fdSsyuu POW_TAG_OP_CLR_NSCHED, /* op == CLR_NSCHED */ 3014a04f2fdSsyuu 0, /* qos (not used for CLR_NSCHED) */ 3024a04f2fdSsyuu 0, /* grp (not used for CLR_NSCHED) */ 3034a04f2fdSsyuu 0, /* type (not used for CLR_NSCHED) */ 3044a04f2fdSsyuu 0); /* tag (not used for CLR_NSCHED) */ 3054a04f2fdSsyuu } 3064a04f2fdSsyuu 3074a04f2fdSsyuu /* NOP */ 3084a04f2fdSsyuu 3094a04f2fdSsyuu static inline void 3104a04f2fdSsyuu cn30xxpow_ops_nop(void) 3114a04f2fdSsyuu { 3124a04f2fdSsyuu cn30xxpow_store( 3134a04f2fdSsyuu 1, /* subdid == 1 */ 3144a04f2fdSsyuu 0, /* addr (not used for NOP) */ 3154a04f2fdSsyuu 0, /* no_sched (not used for NOP) */ 3164a04f2fdSsyuu 0, /* index (not used for NOP) */ 3174a04f2fdSsyuu POW_TAG_OP_NOP, /* op == NOP */ 3184a04f2fdSsyuu 0, /* qos (not used for NOP) */ 3194a04f2fdSsyuu 0, /* grp (not used for NOP) */ 3204a04f2fdSsyuu 0, /* type (not used for NOP) */ 3214a04f2fdSsyuu 0); /* tag (not used for NOP) */ 3224a04f2fdSsyuu } 3234a04f2fdSsyuu 3244e19228dSvisa /* 3254e19228dSvisa * Check if there is a pending POW tag switch. 3264e19228dSvisa */ 3274e19228dSvisa static inline int 3284e19228dSvisa cn30xxpow_tag_sw_pending(void) 3294e19228dSvisa { 3304e19228dSvisa int result; 3314e19228dSvisa 3324e19228dSvisa /* 3334e19228dSvisa * "RDHWR rt, $30" returns: 3344e19228dSvisa * 0 => pending bit is set 3354e19228dSvisa * 1 => pending bit is clear 3364e19228dSvisa */ 3374e19228dSvisa 3384e19228dSvisa __asm volatile ( 3394e19228dSvisa " .set push\n" 3404e19228dSvisa " .set noreorder\n" 3414e19228dSvisa " .set arch=mips64r2\n" 3424e19228dSvisa " rdhwr %0, $30\n" 3434e19228dSvisa " .set pop\n" 3444e19228dSvisa : "=r" (result)); 3454e19228dSvisa return result == 0; 3464e19228dSvisa } 3474e19228dSvisa 3484e19228dSvisa /* 3494e19228dSvisa * Wait until there is no pending POW tag switch. 3504e19228dSvisa */ 3514e19228dSvisa static inline void 3524e19228dSvisa cn30xxpow_tag_sw_wait(void) 3534e19228dSvisa { 3544e19228dSvisa while (cn30xxpow_tag_sw_pending()) 3554e19228dSvisa continue; 3564e19228dSvisa } 3574e19228dSvisa 3584a04f2fdSsyuu /* -------------------------------------------------------------------------- */ 3594a04f2fdSsyuu 3604a04f2fdSsyuu /* 3614a04f2fdSsyuu * global functions 3624a04f2fdSsyuu */ 3634a04f2fdSsyuu void cn30xxpow_work_request_async(uint64_t, uint64_t); 3644a04f2fdSsyuu uint64_t *cn30xxpow_work_response_async(uint64_t); 3654a04f2fdSsyuu void cn30xxpow_ops_swtag(int, uint32_t); 3664a04f2fdSsyuu void cn30xxpow_intr_set_freedback_queue(int, void *); 3674a04f2fdSsyuu 3684a04f2fdSsyuu static inline void 3694a04f2fdSsyuu cn30xxpow_config_int_pc(struct cn30xxpow_softc *sc, int unit) 3704a04f2fdSsyuu { 3714a04f2fdSsyuu uint64_t wq_int_pc; 3724a04f2fdSsyuu uint64_t pc_thr; 3734a04f2fdSsyuu static uint64_t cpu_clock_hz; 3744a04f2fdSsyuu 3754a04f2fdSsyuu if (cpu_clock_hz == 0) 3764a04f2fdSsyuu cpu_clock_hz = curcpu()->ci_hw.clock; 3774a04f2fdSsyuu 3784a04f2fdSsyuu #if 0 3794a04f2fdSsyuu /* from Documents */ 3804a04f2fdSsyuu /* 3814a04f2fdSsyuu * => counter value is POW_WQ_INT_PC[PC_THR] * 256 + 255 3824a04f2fdSsyuu * => counter is decremented every CPU clock 3834a04f2fdSsyuu * => counter is reset when interrupt occurs 3844a04f2fdSsyuu * 3854a04f2fdSsyuu * cpu_clock_per_sec 3864a04f2fdSsyuu * = cpu_clock_mhz * 1000000 3874a04f2fdSsyuu * cpu_clock_per_msec 3884a04f2fdSsyuu * = cpu_clock_mhz * 1000 3894a04f2fdSsyuu * cpu_clock_per_usec 3904a04f2fdSsyuu * = cpu_clock_mhz 3914a04f2fdSsyuu * 3924a04f2fdSsyuu * pc_thr_for_1sec * 256 + 255 3934a04f2fdSsyuu * = cpu_clock_mhz * 1000000 3944a04f2fdSsyuu * pc_thr_for_1sec 3954a04f2fdSsyuu * = ((cpu_clock_mhz * 1000000) - 255) / 256 3964a04f2fdSsyuu * 3974a04f2fdSsyuu * pc_thr_for_1msec * 256 + 255 3984a04f2fdSsyuu * = cpu_clock_mhz * 1000 3994a04f2fdSsyuu * pc_thr_for_1msec 4004a04f2fdSsyuu * = ((cpu_clock_mhz * 1000) - 255) / 256 4014a04f2fdSsyuu * 4024a04f2fdSsyuu * pc_thr_for_1usec * 256 + 255 4034a04f2fdSsyuu * = cpu_clock_mhz 4044a04f2fdSsyuu * pc_thr_for_1usec 4054a04f2fdSsyuu * = (cpu_clock_mhz - 255) / 256 4064a04f2fdSsyuu */ 4074a04f2fdSsyuu pc_thr = (((cpu_clock_hz / 1000000) * (unit)) - 255) / 256; 4084a04f2fdSsyuu #else 4094a04f2fdSsyuu pc_thr = (cpu_clock_hz) / (unit * 16 * 256); 4104a04f2fdSsyuu #endif 4114a04f2fdSsyuu wq_int_pc = pc_thr << POW_WQ_INT_PC_PC_THR_SHIFT; 4124a04f2fdSsyuu _POW_WR8(sc, POW_WQ_INT_PC_OFFSET, wq_int_pc); 4134a04f2fdSsyuu } 4144a04f2fdSsyuu 4154a04f2fdSsyuu static inline void 4164a04f2fdSsyuu cn30xxpow_config_int_pc_rate(struct cn30xxpow_softc *sc, int rate) 4174a04f2fdSsyuu { 4184a04f2fdSsyuu cn30xxpow_config_int_pc(sc, sc->sc_int_pc_base / rate); 4194a04f2fdSsyuu } 4204a04f2fdSsyuu 4214a04f2fdSsyuu #endif /* _CN30XXPOWVAR_H_ */ 422