18c2ecf20Sopenharmony_ci/***********************license start*************** 28c2ecf20Sopenharmony_ci * Author: Cavium Networks 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Contact: support@caviumnetworks.com 58c2ecf20Sopenharmony_ci * This file is part of the OCTEON SDK 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (c) 2003-2008 Cavium Networks 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * This file is free software; you can redistribute it and/or modify 108c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License, Version 2, as 118c2ecf20Sopenharmony_ci * published by the Free Software Foundation. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * This file is distributed in the hope that it will be useful, but 148c2ecf20Sopenharmony_ci * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 158c2ecf20Sopenharmony_ci * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 168c2ecf20Sopenharmony_ci * NONINFRINGEMENT. See the GNU General Public License for more 178c2ecf20Sopenharmony_ci * details. 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * You should have received a copy of the GNU General Public License 208c2ecf20Sopenharmony_ci * along with this file; if not, write to the Free Software 218c2ecf20Sopenharmony_ci * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 228c2ecf20Sopenharmony_ci * or visit http://www.gnu.org/licenses/. 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * This file may also be available under a different license from Cavium. 258c2ecf20Sopenharmony_ci * Contact Cavium Networks for more information 268c2ecf20Sopenharmony_ci ***********************license end**************************************/ 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/** 298c2ecf20Sopenharmony_ci * Interface to the hardware Packet Order / Work unit. 308c2ecf20Sopenharmony_ci * 318c2ecf20Sopenharmony_ci * New, starting with SDK 1.7.0, cvmx-pow supports a number of 328c2ecf20Sopenharmony_ci * extended consistency checks. The define 338c2ecf20Sopenharmony_ci * CVMX_ENABLE_POW_CHECKS controls the runtime insertion of POW 348c2ecf20Sopenharmony_ci * internal state checks to find common programming errors. If 358c2ecf20Sopenharmony_ci * CVMX_ENABLE_POW_CHECKS is not defined, checks are by default 368c2ecf20Sopenharmony_ci * enabled. For example, cvmx-pow will check for the following 378c2ecf20Sopenharmony_ci * program errors or POW state inconsistency. 388c2ecf20Sopenharmony_ci * - Requesting a POW operation with an active tag switch in 398c2ecf20Sopenharmony_ci * progress. 408c2ecf20Sopenharmony_ci * - Waiting for a tag switch to complete for an excessively 418c2ecf20Sopenharmony_ci * long period. This is normally a sign of an error in locking 428c2ecf20Sopenharmony_ci * causing deadlock. 438c2ecf20Sopenharmony_ci * - Illegal tag switches from NULL_NULL. 448c2ecf20Sopenharmony_ci * - Illegal tag switches from NULL. 458c2ecf20Sopenharmony_ci * - Illegal deschedule request. 468c2ecf20Sopenharmony_ci * - WQE pointer not matching the one attached to the core by 478c2ecf20Sopenharmony_ci * the POW. 488c2ecf20Sopenharmony_ci * 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#ifndef __CVMX_POW_H__ 528c2ecf20Sopenharmony_ci#define __CVMX_POW_H__ 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-pow-defs.h> 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-scratch.h> 578c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-wqe.h> 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci/* Default to having all POW constancy checks turned on */ 608c2ecf20Sopenharmony_ci#ifndef CVMX_ENABLE_POW_CHECKS 618c2ecf20Sopenharmony_ci#define CVMX_ENABLE_POW_CHECKS 1 628c2ecf20Sopenharmony_ci#endif 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cienum cvmx_pow_tag_type { 658c2ecf20Sopenharmony_ci /* Tag ordering is maintained */ 668c2ecf20Sopenharmony_ci CVMX_POW_TAG_TYPE_ORDERED = 0L, 678c2ecf20Sopenharmony_ci /* Tag ordering is maintained, and at most one PP has the tag */ 688c2ecf20Sopenharmony_ci CVMX_POW_TAG_TYPE_ATOMIC = 1L, 698c2ecf20Sopenharmony_ci /* 708c2ecf20Sopenharmony_ci * The work queue entry from the order - NEVER tag switch from 718c2ecf20Sopenharmony_ci * NULL to NULL 728c2ecf20Sopenharmony_ci */ 738c2ecf20Sopenharmony_ci CVMX_POW_TAG_TYPE_NULL = 2L, 748c2ecf20Sopenharmony_ci /* A tag switch to NULL, and there is no space reserved in POW 758c2ecf20Sopenharmony_ci * - NEVER tag switch to NULL_NULL 768c2ecf20Sopenharmony_ci * - NEVER tag switch from NULL_NULL 778c2ecf20Sopenharmony_ci * - NULL_NULL is entered at the beginning of time and on a deschedule. 788c2ecf20Sopenharmony_ci * - NULL_NULL can be exited by a new work request. A NULL_SWITCH 798c2ecf20Sopenharmony_ci * load can also switch the state to NULL 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ci CVMX_POW_TAG_TYPE_NULL_NULL = 3L 828c2ecf20Sopenharmony_ci}; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci/** 858c2ecf20Sopenharmony_ci * Wait flag values for pow functions. 868c2ecf20Sopenharmony_ci */ 878c2ecf20Sopenharmony_citypedef enum { 888c2ecf20Sopenharmony_ci CVMX_POW_WAIT = 1, 898c2ecf20Sopenharmony_ci CVMX_POW_NO_WAIT = 0, 908c2ecf20Sopenharmony_ci} cvmx_pow_wait_t; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci/** 938c2ecf20Sopenharmony_ci * POW tag operations. These are used in the data stored to the POW. 948c2ecf20Sopenharmony_ci */ 958c2ecf20Sopenharmony_citypedef enum { 968c2ecf20Sopenharmony_ci /* 978c2ecf20Sopenharmony_ci * switch the tag (only) for this PP 988c2ecf20Sopenharmony_ci * - the previous tag should be non-NULL in this case 998c2ecf20Sopenharmony_ci * - tag switch response required 1008c2ecf20Sopenharmony_ci * - fields used: op, type, tag 1018c2ecf20Sopenharmony_ci */ 1028c2ecf20Sopenharmony_ci CVMX_POW_TAG_OP_SWTAG = 0L, 1038c2ecf20Sopenharmony_ci /* 1048c2ecf20Sopenharmony_ci * switch the tag for this PP, with full information 1058c2ecf20Sopenharmony_ci * - this should be used when the previous tag is NULL 1068c2ecf20Sopenharmony_ci * - tag switch response required 1078c2ecf20Sopenharmony_ci * - fields used: address, op, grp, type, tag 1088c2ecf20Sopenharmony_ci */ 1098c2ecf20Sopenharmony_ci CVMX_POW_TAG_OP_SWTAG_FULL = 1L, 1108c2ecf20Sopenharmony_ci /* 1118c2ecf20Sopenharmony_ci * switch the tag (and/or group) for this PP and de-schedule 1128c2ecf20Sopenharmony_ci * - OK to keep the tag the same and only change the group 1138c2ecf20Sopenharmony_ci * - fields used: op, no_sched, grp, type, tag 1148c2ecf20Sopenharmony_ci */ 1158c2ecf20Sopenharmony_ci CVMX_POW_TAG_OP_SWTAG_DESCH = 2L, 1168c2ecf20Sopenharmony_ci /* 1178c2ecf20Sopenharmony_ci * just de-schedule 1188c2ecf20Sopenharmony_ci * - fields used: op, no_sched 1198c2ecf20Sopenharmony_ci */ 1208c2ecf20Sopenharmony_ci CVMX_POW_TAG_OP_DESCH = 3L, 1218c2ecf20Sopenharmony_ci /* 1228c2ecf20Sopenharmony_ci * create an entirely new work queue entry 1238c2ecf20Sopenharmony_ci * - fields used: address, op, qos, grp, type, tag 1248c2ecf20Sopenharmony_ci */ 1258c2ecf20Sopenharmony_ci CVMX_POW_TAG_OP_ADDWQ = 4L, 1268c2ecf20Sopenharmony_ci /* 1278c2ecf20Sopenharmony_ci * just update the work queue pointer and grp for this PP 1288c2ecf20Sopenharmony_ci * - fields used: address, op, grp 1298c2ecf20Sopenharmony_ci */ 1308c2ecf20Sopenharmony_ci CVMX_POW_TAG_OP_UPDATE_WQP_GRP = 5L, 1318c2ecf20Sopenharmony_ci /* 1328c2ecf20Sopenharmony_ci * set the no_sched bit on the de-schedule list 1338c2ecf20Sopenharmony_ci * 1348c2ecf20Sopenharmony_ci * - does nothing if the selected entry is not on the 1358c2ecf20Sopenharmony_ci * de-schedule list 1368c2ecf20Sopenharmony_ci * 1378c2ecf20Sopenharmony_ci * - does nothing if the stored work queue pointer does not 1388c2ecf20Sopenharmony_ci * match the address field 1398c2ecf20Sopenharmony_ci * 1408c2ecf20Sopenharmony_ci * - fields used: address, index, op 1418c2ecf20Sopenharmony_ci * 1428c2ecf20Sopenharmony_ci * Before issuing a *_NSCHED operation, SW must guarantee 1438c2ecf20Sopenharmony_ci * that all prior deschedules and set/clr NSCHED operations 1448c2ecf20Sopenharmony_ci * are complete and all prior switches are complete. The 1458c2ecf20Sopenharmony_ci * hardware provides the opsdone bit and swdone bit for SW 1468c2ecf20Sopenharmony_ci * polling. After issuing a *_NSCHED operation, SW must 1478c2ecf20Sopenharmony_ci * guarantee that the set/clr NSCHED is complete before any 1488c2ecf20Sopenharmony_ci * subsequent operations. 1498c2ecf20Sopenharmony_ci */ 1508c2ecf20Sopenharmony_ci CVMX_POW_TAG_OP_SET_NSCHED = 6L, 1518c2ecf20Sopenharmony_ci /* 1528c2ecf20Sopenharmony_ci * clears the no_sched bit on the de-schedule list 1538c2ecf20Sopenharmony_ci * 1548c2ecf20Sopenharmony_ci * - does nothing if the selected entry is not on the 1558c2ecf20Sopenharmony_ci * de-schedule list 1568c2ecf20Sopenharmony_ci * 1578c2ecf20Sopenharmony_ci * - does nothing if the stored work queue pointer does not 1588c2ecf20Sopenharmony_ci * match the address field 1598c2ecf20Sopenharmony_ci * 1608c2ecf20Sopenharmony_ci * - fields used: address, index, op 1618c2ecf20Sopenharmony_ci * 1628c2ecf20Sopenharmony_ci * Before issuing a *_NSCHED operation, SW must guarantee that 1638c2ecf20Sopenharmony_ci * all prior deschedules and set/clr NSCHED operations are 1648c2ecf20Sopenharmony_ci * complete and all prior switches are complete. The hardware 1658c2ecf20Sopenharmony_ci * provides the opsdone bit and swdone bit for SW 1668c2ecf20Sopenharmony_ci * polling. After issuing a *_NSCHED operation, SW must 1678c2ecf20Sopenharmony_ci * guarantee that the set/clr NSCHED is complete before any 1688c2ecf20Sopenharmony_ci * subsequent operations. 1698c2ecf20Sopenharmony_ci */ 1708c2ecf20Sopenharmony_ci CVMX_POW_TAG_OP_CLR_NSCHED = 7L, 1718c2ecf20Sopenharmony_ci /* do nothing */ 1728c2ecf20Sopenharmony_ci CVMX_POW_TAG_OP_NOP = 15L 1738c2ecf20Sopenharmony_ci} cvmx_pow_tag_op_t; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci/** 1768c2ecf20Sopenharmony_ci * This structure defines the store data on a store to POW 1778c2ecf20Sopenharmony_ci */ 1788c2ecf20Sopenharmony_citypedef union { 1798c2ecf20Sopenharmony_ci uint64_t u64; 1808c2ecf20Sopenharmony_ci struct { 1818c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 1828c2ecf20Sopenharmony_ci /* 1838c2ecf20Sopenharmony_ci * Don't reschedule this entry. no_sched is used for 1848c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_SWTAG_DESCH and 1858c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_DESCH 1868c2ecf20Sopenharmony_ci */ 1878c2ecf20Sopenharmony_ci uint64_t no_sched:1; 1888c2ecf20Sopenharmony_ci uint64_t unused:2; 1898c2ecf20Sopenharmony_ci /* Tontains index of entry for a CVMX_POW_TAG_OP_*_NSCHED */ 1908c2ecf20Sopenharmony_ci uint64_t index:13; 1918c2ecf20Sopenharmony_ci /* The operation to perform */ 1928c2ecf20Sopenharmony_ci cvmx_pow_tag_op_t op:4; 1938c2ecf20Sopenharmony_ci uint64_t unused2:2; 1948c2ecf20Sopenharmony_ci /* 1958c2ecf20Sopenharmony_ci * The QOS level for the packet. qos is only used for 1968c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_ADDWQ 1978c2ecf20Sopenharmony_ci */ 1988c2ecf20Sopenharmony_ci uint64_t qos:3; 1998c2ecf20Sopenharmony_ci /* 2008c2ecf20Sopenharmony_ci * The group that the work queue entry will be 2018c2ecf20Sopenharmony_ci * scheduled to grp is used for CVMX_POW_TAG_OP_ADDWQ, 2028c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_SWTAG_FULL, 2038c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_SWTAG_DESCH, and 2048c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_UPDATE_WQP_GRP 2058c2ecf20Sopenharmony_ci */ 2068c2ecf20Sopenharmony_ci uint64_t grp:4; 2078c2ecf20Sopenharmony_ci /* 2088c2ecf20Sopenharmony_ci * The type of the tag. type is used for everything 2098c2ecf20Sopenharmony_ci * except CVMX_POW_TAG_OP_DESCH, 2108c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and 2118c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_*_NSCHED 2128c2ecf20Sopenharmony_ci */ 2138c2ecf20Sopenharmony_ci uint64_t type:3; 2148c2ecf20Sopenharmony_ci /* 2158c2ecf20Sopenharmony_ci * The actual tag. tag is used for everything except 2168c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_DESCH, 2178c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and 2188c2ecf20Sopenharmony_ci * CVMX_POW_TAG_OP_*_NSCHED 2198c2ecf20Sopenharmony_ci */ 2208c2ecf20Sopenharmony_ci uint64_t tag:32; 2218c2ecf20Sopenharmony_ci#else 2228c2ecf20Sopenharmony_ci uint64_t tag:32; 2238c2ecf20Sopenharmony_ci uint64_t type:3; 2248c2ecf20Sopenharmony_ci uint64_t grp:4; 2258c2ecf20Sopenharmony_ci uint64_t qos:3; 2268c2ecf20Sopenharmony_ci uint64_t unused2:2; 2278c2ecf20Sopenharmony_ci cvmx_pow_tag_op_t op:4; 2288c2ecf20Sopenharmony_ci uint64_t index:13; 2298c2ecf20Sopenharmony_ci uint64_t unused:2; 2308c2ecf20Sopenharmony_ci uint64_t no_sched:1; 2318c2ecf20Sopenharmony_ci#endif 2328c2ecf20Sopenharmony_ci } s; 2338c2ecf20Sopenharmony_ci} cvmx_pow_tag_req_t; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci/** 2368c2ecf20Sopenharmony_ci * This structure describes the address to load stuff from POW 2378c2ecf20Sopenharmony_ci */ 2388c2ecf20Sopenharmony_citypedef union { 2398c2ecf20Sopenharmony_ci uint64_t u64; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci /** 2428c2ecf20Sopenharmony_ci * Address for new work request loads (did<2:0> == 0) 2438c2ecf20Sopenharmony_ci */ 2448c2ecf20Sopenharmony_ci struct { 2458c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 2468c2ecf20Sopenharmony_ci /* Mips64 address region. Should be CVMX_IO_SEG */ 2478c2ecf20Sopenharmony_ci uint64_t mem_region:2; 2488c2ecf20Sopenharmony_ci /* Must be zero */ 2498c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 2508c2ecf20Sopenharmony_ci /* Must be one */ 2518c2ecf20Sopenharmony_ci uint64_t is_io:1; 2528c2ecf20Sopenharmony_ci /* the ID of POW -- did<2:0> == 0 in this case */ 2538c2ecf20Sopenharmony_ci uint64_t did:8; 2548c2ecf20Sopenharmony_ci /* Must be zero */ 2558c2ecf20Sopenharmony_ci uint64_t reserved_4_39:36; 2568c2ecf20Sopenharmony_ci /* 2578c2ecf20Sopenharmony_ci * If set, don't return load response until work is 2588c2ecf20Sopenharmony_ci * available. 2598c2ecf20Sopenharmony_ci */ 2608c2ecf20Sopenharmony_ci uint64_t wait:1; 2618c2ecf20Sopenharmony_ci /* Must be zero */ 2628c2ecf20Sopenharmony_ci uint64_t reserved_0_2:3; 2638c2ecf20Sopenharmony_ci#else 2648c2ecf20Sopenharmony_ci uint64_t reserved_0_2:3; 2658c2ecf20Sopenharmony_ci uint64_t wait:1; 2668c2ecf20Sopenharmony_ci uint64_t reserved_4_39:36; 2678c2ecf20Sopenharmony_ci uint64_t did:8; 2688c2ecf20Sopenharmony_ci uint64_t is_io:1; 2698c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 2708c2ecf20Sopenharmony_ci uint64_t mem_region:2; 2718c2ecf20Sopenharmony_ci#endif 2728c2ecf20Sopenharmony_ci } swork; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci /** 2758c2ecf20Sopenharmony_ci * Address for loads to get POW internal status 2768c2ecf20Sopenharmony_ci */ 2778c2ecf20Sopenharmony_ci struct { 2788c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 2798c2ecf20Sopenharmony_ci /* Mips64 address region. Should be CVMX_IO_SEG */ 2808c2ecf20Sopenharmony_ci uint64_t mem_region:2; 2818c2ecf20Sopenharmony_ci /* Must be zero */ 2828c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 2838c2ecf20Sopenharmony_ci /* Must be one */ 2848c2ecf20Sopenharmony_ci uint64_t is_io:1; 2858c2ecf20Sopenharmony_ci /* the ID of POW -- did<2:0> == 1 in this case */ 2868c2ecf20Sopenharmony_ci uint64_t did:8; 2878c2ecf20Sopenharmony_ci /* Must be zero */ 2888c2ecf20Sopenharmony_ci uint64_t reserved_10_39:30; 2898c2ecf20Sopenharmony_ci /* The core id to get status for */ 2908c2ecf20Sopenharmony_ci uint64_t coreid:4; 2918c2ecf20Sopenharmony_ci /* 2928c2ecf20Sopenharmony_ci * If set and get_cur is set, return reverse tag-list 2938c2ecf20Sopenharmony_ci * pointer rather than forward tag-list pointer. 2948c2ecf20Sopenharmony_ci */ 2958c2ecf20Sopenharmony_ci uint64_t get_rev:1; 2968c2ecf20Sopenharmony_ci /* 2978c2ecf20Sopenharmony_ci * If set, return current status rather than pending 2988c2ecf20Sopenharmony_ci * status. 2998c2ecf20Sopenharmony_ci */ 3008c2ecf20Sopenharmony_ci uint64_t get_cur:1; 3018c2ecf20Sopenharmony_ci /* 3028c2ecf20Sopenharmony_ci * If set, get the work-queue pointer rather than 3038c2ecf20Sopenharmony_ci * tag/type. 3048c2ecf20Sopenharmony_ci */ 3058c2ecf20Sopenharmony_ci uint64_t get_wqp:1; 3068c2ecf20Sopenharmony_ci /* Must be zero */ 3078c2ecf20Sopenharmony_ci uint64_t reserved_0_2:3; 3088c2ecf20Sopenharmony_ci#else 3098c2ecf20Sopenharmony_ci uint64_t reserved_0_2:3; 3108c2ecf20Sopenharmony_ci uint64_t get_wqp:1; 3118c2ecf20Sopenharmony_ci uint64_t get_cur:1; 3128c2ecf20Sopenharmony_ci uint64_t get_rev:1; 3138c2ecf20Sopenharmony_ci uint64_t coreid:4; 3148c2ecf20Sopenharmony_ci uint64_t reserved_10_39:30; 3158c2ecf20Sopenharmony_ci uint64_t did:8; 3168c2ecf20Sopenharmony_ci uint64_t is_io:1; 3178c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 3188c2ecf20Sopenharmony_ci uint64_t mem_region:2; 3198c2ecf20Sopenharmony_ci#endif 3208c2ecf20Sopenharmony_ci } sstatus; 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci /** 3238c2ecf20Sopenharmony_ci * Address for memory loads to get POW internal state 3248c2ecf20Sopenharmony_ci */ 3258c2ecf20Sopenharmony_ci struct { 3268c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 3278c2ecf20Sopenharmony_ci /* Mips64 address region. Should be CVMX_IO_SEG */ 3288c2ecf20Sopenharmony_ci uint64_t mem_region:2; 3298c2ecf20Sopenharmony_ci /* Must be zero */ 3308c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 3318c2ecf20Sopenharmony_ci /* Must be one */ 3328c2ecf20Sopenharmony_ci uint64_t is_io:1; 3338c2ecf20Sopenharmony_ci /* the ID of POW -- did<2:0> == 2 in this case */ 3348c2ecf20Sopenharmony_ci uint64_t did:8; 3358c2ecf20Sopenharmony_ci /* Must be zero */ 3368c2ecf20Sopenharmony_ci uint64_t reserved_16_39:24; 3378c2ecf20Sopenharmony_ci /* POW memory index */ 3388c2ecf20Sopenharmony_ci uint64_t index:11; 3398c2ecf20Sopenharmony_ci /* 3408c2ecf20Sopenharmony_ci * If set, return deschedule information rather than 3418c2ecf20Sopenharmony_ci * the standard response for work-queue index (invalid 3428c2ecf20Sopenharmony_ci * if the work-queue entry is not on the deschedule 3438c2ecf20Sopenharmony_ci * list). 3448c2ecf20Sopenharmony_ci */ 3458c2ecf20Sopenharmony_ci uint64_t get_des:1; 3468c2ecf20Sopenharmony_ci /* 3478c2ecf20Sopenharmony_ci * If set, get the work-queue pointer rather than 3488c2ecf20Sopenharmony_ci * tag/type (no effect when get_des set). 3498c2ecf20Sopenharmony_ci */ 3508c2ecf20Sopenharmony_ci uint64_t get_wqp:1; 3518c2ecf20Sopenharmony_ci /* Must be zero */ 3528c2ecf20Sopenharmony_ci uint64_t reserved_0_2:3; 3538c2ecf20Sopenharmony_ci#else 3548c2ecf20Sopenharmony_ci uint64_t reserved_0_2:3; 3558c2ecf20Sopenharmony_ci uint64_t get_wqp:1; 3568c2ecf20Sopenharmony_ci uint64_t get_des:1; 3578c2ecf20Sopenharmony_ci uint64_t index:11; 3588c2ecf20Sopenharmony_ci uint64_t reserved_16_39:24; 3598c2ecf20Sopenharmony_ci uint64_t did:8; 3608c2ecf20Sopenharmony_ci uint64_t is_io:1; 3618c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 3628c2ecf20Sopenharmony_ci uint64_t mem_region:2; 3638c2ecf20Sopenharmony_ci#endif 3648c2ecf20Sopenharmony_ci } smemload; 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci /** 3678c2ecf20Sopenharmony_ci * Address for index/pointer loads 3688c2ecf20Sopenharmony_ci */ 3698c2ecf20Sopenharmony_ci struct { 3708c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 3718c2ecf20Sopenharmony_ci /* Mips64 address region. Should be CVMX_IO_SEG */ 3728c2ecf20Sopenharmony_ci uint64_t mem_region:2; 3738c2ecf20Sopenharmony_ci /* Must be zero */ 3748c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 3758c2ecf20Sopenharmony_ci /* Must be one */ 3768c2ecf20Sopenharmony_ci uint64_t is_io:1; 3778c2ecf20Sopenharmony_ci /* the ID of POW -- did<2:0> == 3 in this case */ 3788c2ecf20Sopenharmony_ci uint64_t did:8; 3798c2ecf20Sopenharmony_ci /* Must be zero */ 3808c2ecf20Sopenharmony_ci uint64_t reserved_9_39:31; 3818c2ecf20Sopenharmony_ci /* 3828c2ecf20Sopenharmony_ci * when {get_rmt ==0 AND get_des_get_tail == 0}, this 3838c2ecf20Sopenharmony_ci * field selects one of eight POW internal-input 3848c2ecf20Sopenharmony_ci * queues (0-7), one per QOS level; values 8-15 are 3858c2ecf20Sopenharmony_ci * illegal in this case; when {get_rmt ==0 AND 3868c2ecf20Sopenharmony_ci * get_des_get_tail == 1}, this field selects one of 3878c2ecf20Sopenharmony_ci * 16 deschedule lists (per group); when get_rmt ==1, 3888c2ecf20Sopenharmony_ci * this field selects one of 16 memory-input queue 3898c2ecf20Sopenharmony_ci * lists. The two memory-input queue lists associated 3908c2ecf20Sopenharmony_ci * with each QOS level are: 3918c2ecf20Sopenharmony_ci * 3928c2ecf20Sopenharmony_ci * - qosgrp = 0, qosgrp = 8: QOS0 3938c2ecf20Sopenharmony_ci * - qosgrp = 1, qosgrp = 9: QOS1 3948c2ecf20Sopenharmony_ci * - qosgrp = 2, qosgrp = 10: QOS2 3958c2ecf20Sopenharmony_ci * - qosgrp = 3, qosgrp = 11: QOS3 3968c2ecf20Sopenharmony_ci * - qosgrp = 4, qosgrp = 12: QOS4 3978c2ecf20Sopenharmony_ci * - qosgrp = 5, qosgrp = 13: QOS5 3988c2ecf20Sopenharmony_ci * - qosgrp = 6, qosgrp = 14: QOS6 3998c2ecf20Sopenharmony_ci * - qosgrp = 7, qosgrp = 15: QOS7 4008c2ecf20Sopenharmony_ci */ 4018c2ecf20Sopenharmony_ci uint64_t qosgrp:4; 4028c2ecf20Sopenharmony_ci /* 4038c2ecf20Sopenharmony_ci * If set and get_rmt is clear, return deschedule list 4048c2ecf20Sopenharmony_ci * indexes rather than indexes for the specified qos 4058c2ecf20Sopenharmony_ci * level; if set and get_rmt is set, return the tail 4068c2ecf20Sopenharmony_ci * pointer rather than the head pointer for the 4078c2ecf20Sopenharmony_ci * specified qos level. 4088c2ecf20Sopenharmony_ci */ 4098c2ecf20Sopenharmony_ci uint64_t get_des_get_tail:1; 4108c2ecf20Sopenharmony_ci /* 4118c2ecf20Sopenharmony_ci * If set, return remote pointers rather than the 4128c2ecf20Sopenharmony_ci * local indexes for the specified qos level. 4138c2ecf20Sopenharmony_ci */ 4148c2ecf20Sopenharmony_ci uint64_t get_rmt:1; 4158c2ecf20Sopenharmony_ci /* Must be zero */ 4168c2ecf20Sopenharmony_ci uint64_t reserved_0_2:3; 4178c2ecf20Sopenharmony_ci#else 4188c2ecf20Sopenharmony_ci uint64_t reserved_0_2:3; 4198c2ecf20Sopenharmony_ci uint64_t get_rmt:1; 4208c2ecf20Sopenharmony_ci uint64_t get_des_get_tail:1; 4218c2ecf20Sopenharmony_ci uint64_t qosgrp:4; 4228c2ecf20Sopenharmony_ci uint64_t reserved_9_39:31; 4238c2ecf20Sopenharmony_ci uint64_t did:8; 4248c2ecf20Sopenharmony_ci uint64_t is_io:1; 4258c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 4268c2ecf20Sopenharmony_ci uint64_t mem_region:2; 4278c2ecf20Sopenharmony_ci#endif 4288c2ecf20Sopenharmony_ci } sindexload; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci /** 4318c2ecf20Sopenharmony_ci * address for NULL_RD request (did<2:0> == 4) when this is read, 4328c2ecf20Sopenharmony_ci * HW attempts to change the state to NULL if it is NULL_NULL (the 4338c2ecf20Sopenharmony_ci * hardware cannot switch from NULL_NULL to NULL if a POW entry is 4348c2ecf20Sopenharmony_ci * not available - software may need to recover by finishing 4358c2ecf20Sopenharmony_ci * another piece of work before a POW entry can ever become 4368c2ecf20Sopenharmony_ci * available.) 4378c2ecf20Sopenharmony_ci */ 4388c2ecf20Sopenharmony_ci struct { 4398c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 4408c2ecf20Sopenharmony_ci /* Mips64 address region. Should be CVMX_IO_SEG */ 4418c2ecf20Sopenharmony_ci uint64_t mem_region:2; 4428c2ecf20Sopenharmony_ci /* Must be zero */ 4438c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 4448c2ecf20Sopenharmony_ci /* Must be one */ 4458c2ecf20Sopenharmony_ci uint64_t is_io:1; 4468c2ecf20Sopenharmony_ci /* the ID of POW -- did<2:0> == 4 in this case */ 4478c2ecf20Sopenharmony_ci uint64_t did:8; 4488c2ecf20Sopenharmony_ci /* Must be zero */ 4498c2ecf20Sopenharmony_ci uint64_t reserved_0_39:40; 4508c2ecf20Sopenharmony_ci#else 4518c2ecf20Sopenharmony_ci uint64_t reserved_0_39:40; 4528c2ecf20Sopenharmony_ci uint64_t did:8; 4538c2ecf20Sopenharmony_ci uint64_t is_io:1; 4548c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 4558c2ecf20Sopenharmony_ci uint64_t mem_region:2; 4568c2ecf20Sopenharmony_ci#endif 4578c2ecf20Sopenharmony_ci } snull_rd; 4588c2ecf20Sopenharmony_ci} cvmx_pow_load_addr_t; 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci/** 4618c2ecf20Sopenharmony_ci * This structure defines the response to a load/SENDSINGLE to POW 4628c2ecf20Sopenharmony_ci * (except CSR reads) 4638c2ecf20Sopenharmony_ci */ 4648c2ecf20Sopenharmony_citypedef union { 4658c2ecf20Sopenharmony_ci uint64_t u64; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci /** 4688c2ecf20Sopenharmony_ci * Response to new work request loads 4698c2ecf20Sopenharmony_ci */ 4708c2ecf20Sopenharmony_ci struct { 4718c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 4728c2ecf20Sopenharmony_ci /* 4738c2ecf20Sopenharmony_ci * Set when no new work queue entry was returned. * 4748c2ecf20Sopenharmony_ci * If there was de-scheduled work, the HW will 4758c2ecf20Sopenharmony_ci * definitely return it. When this bit is set, it 4768c2ecf20Sopenharmony_ci * could mean either mean: 4778c2ecf20Sopenharmony_ci * 4788c2ecf20Sopenharmony_ci * - There was no work, or 4798c2ecf20Sopenharmony_ci * 4808c2ecf20Sopenharmony_ci * - There was no work that the HW could find. This 4818c2ecf20Sopenharmony_ci * case can happen, regardless of the wait bit value 4828c2ecf20Sopenharmony_ci * in the original request, when there is work in 4838c2ecf20Sopenharmony_ci * the IQ's that is too deep down the list. 4848c2ecf20Sopenharmony_ci */ 4858c2ecf20Sopenharmony_ci uint64_t no_work:1; 4868c2ecf20Sopenharmony_ci /* Must be zero */ 4878c2ecf20Sopenharmony_ci uint64_t reserved_40_62:23; 4888c2ecf20Sopenharmony_ci /* 36 in O1 -- the work queue pointer */ 4898c2ecf20Sopenharmony_ci uint64_t addr:40; 4908c2ecf20Sopenharmony_ci#else 4918c2ecf20Sopenharmony_ci uint64_t addr:40; 4928c2ecf20Sopenharmony_ci uint64_t reserved_40_62:23; 4938c2ecf20Sopenharmony_ci uint64_t no_work:1; 4948c2ecf20Sopenharmony_ci#endif 4958c2ecf20Sopenharmony_ci } s_work; 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci /** 4988c2ecf20Sopenharmony_ci * Result for a POW Status Load (when get_cur==0 and get_wqp==0) 4998c2ecf20Sopenharmony_ci */ 5008c2ecf20Sopenharmony_ci struct { 5018c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 5028c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 5038c2ecf20Sopenharmony_ci /* Set when there is a pending non-NULL SWTAG or 5048c2ecf20Sopenharmony_ci * SWTAG_FULL, and the POW entry has not left the list 5058c2ecf20Sopenharmony_ci * for the original tag. */ 5068c2ecf20Sopenharmony_ci uint64_t pend_switch:1; 5078c2ecf20Sopenharmony_ci /* Set when SWTAG_FULL and pend_switch is set. */ 5088c2ecf20Sopenharmony_ci uint64_t pend_switch_full:1; 5098c2ecf20Sopenharmony_ci /* 5108c2ecf20Sopenharmony_ci * Set when there is a pending NULL SWTAG, or an 5118c2ecf20Sopenharmony_ci * implicit switch to NULL. 5128c2ecf20Sopenharmony_ci */ 5138c2ecf20Sopenharmony_ci uint64_t pend_switch_null:1; 5148c2ecf20Sopenharmony_ci /* Set when there is a pending DESCHED or SWTAG_DESCHED. */ 5158c2ecf20Sopenharmony_ci uint64_t pend_desched:1; 5168c2ecf20Sopenharmony_ci /* 5178c2ecf20Sopenharmony_ci * Set when there is a pending SWTAG_DESCHED and 5188c2ecf20Sopenharmony_ci * pend_desched is set. 5198c2ecf20Sopenharmony_ci */ 5208c2ecf20Sopenharmony_ci uint64_t pend_desched_switch:1; 5218c2ecf20Sopenharmony_ci /* Set when nosched is desired and pend_desched is set. */ 5228c2ecf20Sopenharmony_ci uint64_t pend_nosched:1; 5238c2ecf20Sopenharmony_ci /* Set when there is a pending GET_WORK. */ 5248c2ecf20Sopenharmony_ci uint64_t pend_new_work:1; 5258c2ecf20Sopenharmony_ci /* 5268c2ecf20Sopenharmony_ci * When pend_new_work is set, this bit indicates that 5278c2ecf20Sopenharmony_ci * the wait bit was set. 5288c2ecf20Sopenharmony_ci */ 5298c2ecf20Sopenharmony_ci uint64_t pend_new_work_wait:1; 5308c2ecf20Sopenharmony_ci /* Set when there is a pending NULL_RD. */ 5318c2ecf20Sopenharmony_ci uint64_t pend_null_rd:1; 5328c2ecf20Sopenharmony_ci /* Set when there is a pending CLR_NSCHED. */ 5338c2ecf20Sopenharmony_ci uint64_t pend_nosched_clr:1; 5348c2ecf20Sopenharmony_ci uint64_t reserved_51:1; 5358c2ecf20Sopenharmony_ci /* This is the index when pend_nosched_clr is set. */ 5368c2ecf20Sopenharmony_ci uint64_t pend_index:11; 5378c2ecf20Sopenharmony_ci /* 5388c2ecf20Sopenharmony_ci * This is the new_grp when (pend_desched AND 5398c2ecf20Sopenharmony_ci * pend_desched_switch) is set. 5408c2ecf20Sopenharmony_ci */ 5418c2ecf20Sopenharmony_ci uint64_t pend_grp:4; 5428c2ecf20Sopenharmony_ci uint64_t reserved_34_35:2; 5438c2ecf20Sopenharmony_ci /* 5448c2ecf20Sopenharmony_ci * This is the tag type when pend_switch or 5458c2ecf20Sopenharmony_ci * (pend_desched AND pend_desched_switch) are set. 5468c2ecf20Sopenharmony_ci */ 5478c2ecf20Sopenharmony_ci uint64_t pend_type:2; 5488c2ecf20Sopenharmony_ci /* 5498c2ecf20Sopenharmony_ci * - this is the tag when pend_switch or (pend_desched 5508c2ecf20Sopenharmony_ci * AND pend_desched_switch) are set. 5518c2ecf20Sopenharmony_ci */ 5528c2ecf20Sopenharmony_ci uint64_t pend_tag:32; 5538c2ecf20Sopenharmony_ci#else 5548c2ecf20Sopenharmony_ci uint64_t pend_tag:32; 5558c2ecf20Sopenharmony_ci uint64_t pend_type:2; 5568c2ecf20Sopenharmony_ci uint64_t reserved_34_35:2; 5578c2ecf20Sopenharmony_ci uint64_t pend_grp:4; 5588c2ecf20Sopenharmony_ci uint64_t pend_index:11; 5598c2ecf20Sopenharmony_ci uint64_t reserved_51:1; 5608c2ecf20Sopenharmony_ci uint64_t pend_nosched_clr:1; 5618c2ecf20Sopenharmony_ci uint64_t pend_null_rd:1; 5628c2ecf20Sopenharmony_ci uint64_t pend_new_work_wait:1; 5638c2ecf20Sopenharmony_ci uint64_t pend_new_work:1; 5648c2ecf20Sopenharmony_ci uint64_t pend_nosched:1; 5658c2ecf20Sopenharmony_ci uint64_t pend_desched_switch:1; 5668c2ecf20Sopenharmony_ci uint64_t pend_desched:1; 5678c2ecf20Sopenharmony_ci uint64_t pend_switch_null:1; 5688c2ecf20Sopenharmony_ci uint64_t pend_switch_full:1; 5698c2ecf20Sopenharmony_ci uint64_t pend_switch:1; 5708c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 5718c2ecf20Sopenharmony_ci#endif 5728c2ecf20Sopenharmony_ci } s_sstatus0; 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci /** 5758c2ecf20Sopenharmony_ci * Result for a POW Status Load (when get_cur==0 and get_wqp==1) 5768c2ecf20Sopenharmony_ci */ 5778c2ecf20Sopenharmony_ci struct { 5788c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 5798c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 5808c2ecf20Sopenharmony_ci /* 5818c2ecf20Sopenharmony_ci * Set when there is a pending non-NULL SWTAG or 5828c2ecf20Sopenharmony_ci * SWTAG_FULL, and the POW entry has not left the list 5838c2ecf20Sopenharmony_ci * for the original tag. 5848c2ecf20Sopenharmony_ci */ 5858c2ecf20Sopenharmony_ci uint64_t pend_switch:1; 5868c2ecf20Sopenharmony_ci /* Set when SWTAG_FULL and pend_switch is set. */ 5878c2ecf20Sopenharmony_ci uint64_t pend_switch_full:1; 5888c2ecf20Sopenharmony_ci /* 5898c2ecf20Sopenharmony_ci * Set when there is a pending NULL SWTAG, or an 5908c2ecf20Sopenharmony_ci * implicit switch to NULL. 5918c2ecf20Sopenharmony_ci */ 5928c2ecf20Sopenharmony_ci uint64_t pend_switch_null:1; 5938c2ecf20Sopenharmony_ci /* 5948c2ecf20Sopenharmony_ci * Set when there is a pending DESCHED or 5958c2ecf20Sopenharmony_ci * SWTAG_DESCHED. 5968c2ecf20Sopenharmony_ci */ 5978c2ecf20Sopenharmony_ci uint64_t pend_desched:1; 5988c2ecf20Sopenharmony_ci /* 5998c2ecf20Sopenharmony_ci * Set when there is a pending SWTAG_DESCHED and 6008c2ecf20Sopenharmony_ci * pend_desched is set. 6018c2ecf20Sopenharmony_ci */ 6028c2ecf20Sopenharmony_ci uint64_t pend_desched_switch:1; 6038c2ecf20Sopenharmony_ci /* Set when nosched is desired and pend_desched is set. */ 6048c2ecf20Sopenharmony_ci uint64_t pend_nosched:1; 6058c2ecf20Sopenharmony_ci /* Set when there is a pending GET_WORK. */ 6068c2ecf20Sopenharmony_ci uint64_t pend_new_work:1; 6078c2ecf20Sopenharmony_ci /* 6088c2ecf20Sopenharmony_ci * When pend_new_work is set, this bit indicates that 6098c2ecf20Sopenharmony_ci * the wait bit was set. 6108c2ecf20Sopenharmony_ci */ 6118c2ecf20Sopenharmony_ci uint64_t pend_new_work_wait:1; 6128c2ecf20Sopenharmony_ci /* Set when there is a pending NULL_RD. */ 6138c2ecf20Sopenharmony_ci uint64_t pend_null_rd:1; 6148c2ecf20Sopenharmony_ci /* Set when there is a pending CLR_NSCHED. */ 6158c2ecf20Sopenharmony_ci uint64_t pend_nosched_clr:1; 6168c2ecf20Sopenharmony_ci uint64_t reserved_51:1; 6178c2ecf20Sopenharmony_ci /* This is the index when pend_nosched_clr is set. */ 6188c2ecf20Sopenharmony_ci uint64_t pend_index:11; 6198c2ecf20Sopenharmony_ci /* 6208c2ecf20Sopenharmony_ci * This is the new_grp when (pend_desched AND 6218c2ecf20Sopenharmony_ci * pend_desched_switch) is set. 6228c2ecf20Sopenharmony_ci */ 6238c2ecf20Sopenharmony_ci uint64_t pend_grp:4; 6248c2ecf20Sopenharmony_ci /* This is the wqp when pend_nosched_clr is set. */ 6258c2ecf20Sopenharmony_ci uint64_t pend_wqp:36; 6268c2ecf20Sopenharmony_ci#else 6278c2ecf20Sopenharmony_ci uint64_t pend_wqp:36; 6288c2ecf20Sopenharmony_ci uint64_t pend_grp:4; 6298c2ecf20Sopenharmony_ci uint64_t pend_index:11; 6308c2ecf20Sopenharmony_ci uint64_t reserved_51:1; 6318c2ecf20Sopenharmony_ci uint64_t pend_nosched_clr:1; 6328c2ecf20Sopenharmony_ci uint64_t pend_null_rd:1; 6338c2ecf20Sopenharmony_ci uint64_t pend_new_work_wait:1; 6348c2ecf20Sopenharmony_ci uint64_t pend_new_work:1; 6358c2ecf20Sopenharmony_ci uint64_t pend_nosched:1; 6368c2ecf20Sopenharmony_ci uint64_t pend_desched_switch:1; 6378c2ecf20Sopenharmony_ci uint64_t pend_desched:1; 6388c2ecf20Sopenharmony_ci uint64_t pend_switch_null:1; 6398c2ecf20Sopenharmony_ci uint64_t pend_switch_full:1; 6408c2ecf20Sopenharmony_ci uint64_t pend_switch:1; 6418c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 6428c2ecf20Sopenharmony_ci#endif 6438c2ecf20Sopenharmony_ci } s_sstatus1; 6448c2ecf20Sopenharmony_ci 6458c2ecf20Sopenharmony_ci /** 6468c2ecf20Sopenharmony_ci * Result for a POW Status Load (when get_cur==1, get_wqp==0, and 6478c2ecf20Sopenharmony_ci * get_rev==0) 6488c2ecf20Sopenharmony_ci */ 6498c2ecf20Sopenharmony_ci struct { 6508c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 6518c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 6528c2ecf20Sopenharmony_ci /* 6538c2ecf20Sopenharmony_ci * Points to the next POW entry in the tag list when 6548c2ecf20Sopenharmony_ci * tail == 0 (and tag_type is not NULL or NULL_NULL). 6558c2ecf20Sopenharmony_ci */ 6568c2ecf20Sopenharmony_ci uint64_t link_index:11; 6578c2ecf20Sopenharmony_ci /* The POW entry attached to the core. */ 6588c2ecf20Sopenharmony_ci uint64_t index:11; 6598c2ecf20Sopenharmony_ci /* 6608c2ecf20Sopenharmony_ci * The group attached to the core (updated when new 6618c2ecf20Sopenharmony_ci * tag list entered on SWTAG_FULL). 6628c2ecf20Sopenharmony_ci */ 6638c2ecf20Sopenharmony_ci uint64_t grp:4; 6648c2ecf20Sopenharmony_ci /* 6658c2ecf20Sopenharmony_ci * Set when this POW entry is at the head of its tag 6668c2ecf20Sopenharmony_ci * list (also set when in the NULL or NULL_NULL 6678c2ecf20Sopenharmony_ci * state). 6688c2ecf20Sopenharmony_ci */ 6698c2ecf20Sopenharmony_ci uint64_t head:1; 6708c2ecf20Sopenharmony_ci /* 6718c2ecf20Sopenharmony_ci * Set when this POW entry is at the tail of its tag 6728c2ecf20Sopenharmony_ci * list (also set when in the NULL or NULL_NULL 6738c2ecf20Sopenharmony_ci * state). 6748c2ecf20Sopenharmony_ci */ 6758c2ecf20Sopenharmony_ci uint64_t tail:1; 6768c2ecf20Sopenharmony_ci /* 6778c2ecf20Sopenharmony_ci * The tag type attached to the core (updated when new 6788c2ecf20Sopenharmony_ci * tag list entered on SWTAG, SWTAG_FULL, or 6798c2ecf20Sopenharmony_ci * SWTAG_DESCHED). 6808c2ecf20Sopenharmony_ci */ 6818c2ecf20Sopenharmony_ci uint64_t tag_type:2; 6828c2ecf20Sopenharmony_ci /* 6838c2ecf20Sopenharmony_ci * The tag attached to the core (updated when new tag 6848c2ecf20Sopenharmony_ci * list entered on SWTAG, SWTAG_FULL, or 6858c2ecf20Sopenharmony_ci * SWTAG_DESCHED). 6868c2ecf20Sopenharmony_ci */ 6878c2ecf20Sopenharmony_ci uint64_t tag:32; 6888c2ecf20Sopenharmony_ci#else 6898c2ecf20Sopenharmony_ci uint64_t tag:32; 6908c2ecf20Sopenharmony_ci uint64_t tag_type:2; 6918c2ecf20Sopenharmony_ci uint64_t tail:1; 6928c2ecf20Sopenharmony_ci uint64_t head:1; 6938c2ecf20Sopenharmony_ci uint64_t grp:4; 6948c2ecf20Sopenharmony_ci uint64_t index:11; 6958c2ecf20Sopenharmony_ci uint64_t link_index:11; 6968c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 6978c2ecf20Sopenharmony_ci#endif 6988c2ecf20Sopenharmony_ci } s_sstatus2; 6998c2ecf20Sopenharmony_ci 7008c2ecf20Sopenharmony_ci /** 7018c2ecf20Sopenharmony_ci * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1) 7028c2ecf20Sopenharmony_ci */ 7038c2ecf20Sopenharmony_ci struct { 7048c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 7058c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 7068c2ecf20Sopenharmony_ci /* 7078c2ecf20Sopenharmony_ci * Points to the prior POW entry in the tag list when 7088c2ecf20Sopenharmony_ci * head == 0 (and tag_type is not NULL or 7098c2ecf20Sopenharmony_ci * NULL_NULL). This field is unpredictable when the 7108c2ecf20Sopenharmony_ci * core's state is NULL or NULL_NULL. 7118c2ecf20Sopenharmony_ci */ 7128c2ecf20Sopenharmony_ci uint64_t revlink_index:11; 7138c2ecf20Sopenharmony_ci /* The POW entry attached to the core. */ 7148c2ecf20Sopenharmony_ci uint64_t index:11; 7158c2ecf20Sopenharmony_ci /* 7168c2ecf20Sopenharmony_ci * The group attached to the core (updated when new 7178c2ecf20Sopenharmony_ci * tag list entered on SWTAG_FULL). 7188c2ecf20Sopenharmony_ci */ 7198c2ecf20Sopenharmony_ci uint64_t grp:4; 7208c2ecf20Sopenharmony_ci /* Set when this POW entry is at the head of its tag 7218c2ecf20Sopenharmony_ci * list (also set when in the NULL or NULL_NULL 7228c2ecf20Sopenharmony_ci * state). 7238c2ecf20Sopenharmony_ci */ 7248c2ecf20Sopenharmony_ci uint64_t head:1; 7258c2ecf20Sopenharmony_ci /* 7268c2ecf20Sopenharmony_ci * Set when this POW entry is at the tail of its tag 7278c2ecf20Sopenharmony_ci * list (also set when in the NULL or NULL_NULL 7288c2ecf20Sopenharmony_ci * state). 7298c2ecf20Sopenharmony_ci */ 7308c2ecf20Sopenharmony_ci uint64_t tail:1; 7318c2ecf20Sopenharmony_ci /* 7328c2ecf20Sopenharmony_ci * The tag type attached to the core (updated when new 7338c2ecf20Sopenharmony_ci * tag list entered on SWTAG, SWTAG_FULL, or 7348c2ecf20Sopenharmony_ci * SWTAG_DESCHED). 7358c2ecf20Sopenharmony_ci */ 7368c2ecf20Sopenharmony_ci uint64_t tag_type:2; 7378c2ecf20Sopenharmony_ci /* 7388c2ecf20Sopenharmony_ci * The tag attached to the core (updated when new tag 7398c2ecf20Sopenharmony_ci * list entered on SWTAG, SWTAG_FULL, or 7408c2ecf20Sopenharmony_ci * SWTAG_DESCHED). 7418c2ecf20Sopenharmony_ci */ 7428c2ecf20Sopenharmony_ci uint64_t tag:32; 7438c2ecf20Sopenharmony_ci#else 7448c2ecf20Sopenharmony_ci uint64_t tag:32; 7458c2ecf20Sopenharmony_ci uint64_t tag_type:2; 7468c2ecf20Sopenharmony_ci uint64_t tail:1; 7478c2ecf20Sopenharmony_ci uint64_t head:1; 7488c2ecf20Sopenharmony_ci uint64_t grp:4; 7498c2ecf20Sopenharmony_ci uint64_t index:11; 7508c2ecf20Sopenharmony_ci uint64_t revlink_index:11; 7518c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 7528c2ecf20Sopenharmony_ci#endif 7538c2ecf20Sopenharmony_ci } s_sstatus3; 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_ci /** 7568c2ecf20Sopenharmony_ci * Result for a POW Status Load (when get_cur==1, get_wqp==1, and 7578c2ecf20Sopenharmony_ci * get_rev==0) 7588c2ecf20Sopenharmony_ci */ 7598c2ecf20Sopenharmony_ci struct { 7608c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 7618c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 7628c2ecf20Sopenharmony_ci /* 7638c2ecf20Sopenharmony_ci * Points to the next POW entry in the tag list when 7648c2ecf20Sopenharmony_ci * tail == 0 (and tag_type is not NULL or NULL_NULL). 7658c2ecf20Sopenharmony_ci */ 7668c2ecf20Sopenharmony_ci uint64_t link_index:11; 7678c2ecf20Sopenharmony_ci /* The POW entry attached to the core. */ 7688c2ecf20Sopenharmony_ci uint64_t index:11; 7698c2ecf20Sopenharmony_ci /* 7708c2ecf20Sopenharmony_ci * The group attached to the core (updated when new 7718c2ecf20Sopenharmony_ci * tag list entered on SWTAG_FULL). 7728c2ecf20Sopenharmony_ci */ 7738c2ecf20Sopenharmony_ci uint64_t grp:4; 7748c2ecf20Sopenharmony_ci /* 7758c2ecf20Sopenharmony_ci * The wqp attached to the core (updated when new tag 7768c2ecf20Sopenharmony_ci * list entered on SWTAG_FULL). 7778c2ecf20Sopenharmony_ci */ 7788c2ecf20Sopenharmony_ci uint64_t wqp:36; 7798c2ecf20Sopenharmony_ci#else 7808c2ecf20Sopenharmony_ci uint64_t wqp:36; 7818c2ecf20Sopenharmony_ci uint64_t grp:4; 7828c2ecf20Sopenharmony_ci uint64_t index:11; 7838c2ecf20Sopenharmony_ci uint64_t link_index:11; 7848c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 7858c2ecf20Sopenharmony_ci#endif 7868c2ecf20Sopenharmony_ci } s_sstatus4; 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci /** 7898c2ecf20Sopenharmony_ci * Result for a POW Status Load (when get_cur==1, get_wqp==1, and 7908c2ecf20Sopenharmony_ci * get_rev==1) 7918c2ecf20Sopenharmony_ci */ 7928c2ecf20Sopenharmony_ci struct { 7938c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 7948c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 7958c2ecf20Sopenharmony_ci /* 7968c2ecf20Sopenharmony_ci * Points to the prior POW entry in the tag list when 7978c2ecf20Sopenharmony_ci * head == 0 (and tag_type is not NULL or 7988c2ecf20Sopenharmony_ci * NULL_NULL). This field is unpredictable when the 7998c2ecf20Sopenharmony_ci * core's state is NULL or NULL_NULL. 8008c2ecf20Sopenharmony_ci */ 8018c2ecf20Sopenharmony_ci uint64_t revlink_index:11; 8028c2ecf20Sopenharmony_ci /* The POW entry attached to the core. */ 8038c2ecf20Sopenharmony_ci uint64_t index:11; 8048c2ecf20Sopenharmony_ci /* 8058c2ecf20Sopenharmony_ci * The group attached to the core (updated when new 8068c2ecf20Sopenharmony_ci * tag list entered on SWTAG_FULL). 8078c2ecf20Sopenharmony_ci */ 8088c2ecf20Sopenharmony_ci uint64_t grp:4; 8098c2ecf20Sopenharmony_ci /* 8108c2ecf20Sopenharmony_ci * The wqp attached to the core (updated when new tag 8118c2ecf20Sopenharmony_ci * list entered on SWTAG_FULL). 8128c2ecf20Sopenharmony_ci */ 8138c2ecf20Sopenharmony_ci uint64_t wqp:36; 8148c2ecf20Sopenharmony_ci#else 8158c2ecf20Sopenharmony_ci uint64_t wqp:36; 8168c2ecf20Sopenharmony_ci uint64_t grp:4; 8178c2ecf20Sopenharmony_ci uint64_t index:11; 8188c2ecf20Sopenharmony_ci uint64_t revlink_index:11; 8198c2ecf20Sopenharmony_ci uint64_t reserved_62_63:2; 8208c2ecf20Sopenharmony_ci#endif 8218c2ecf20Sopenharmony_ci } s_sstatus5; 8228c2ecf20Sopenharmony_ci 8238c2ecf20Sopenharmony_ci /** 8248c2ecf20Sopenharmony_ci * Result For POW Memory Load (get_des == 0 and get_wqp == 0) 8258c2ecf20Sopenharmony_ci */ 8268c2ecf20Sopenharmony_ci struct { 8278c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 8288c2ecf20Sopenharmony_ci uint64_t reserved_51_63:13; 8298c2ecf20Sopenharmony_ci /* 8308c2ecf20Sopenharmony_ci * The next entry in the input, free, descheduled_head 8318c2ecf20Sopenharmony_ci * list (unpredictable if entry is the tail of the 8328c2ecf20Sopenharmony_ci * list). 8338c2ecf20Sopenharmony_ci */ 8348c2ecf20Sopenharmony_ci uint64_t next_index:11; 8358c2ecf20Sopenharmony_ci /* The group of the POW entry. */ 8368c2ecf20Sopenharmony_ci uint64_t grp:4; 8378c2ecf20Sopenharmony_ci uint64_t reserved_35:1; 8388c2ecf20Sopenharmony_ci /* 8398c2ecf20Sopenharmony_ci * Set when this POW entry is at the tail of its tag 8408c2ecf20Sopenharmony_ci * list (also set when in the NULL or NULL_NULL 8418c2ecf20Sopenharmony_ci * state). 8428c2ecf20Sopenharmony_ci */ 8438c2ecf20Sopenharmony_ci uint64_t tail:1; 8448c2ecf20Sopenharmony_ci /* The tag type of the POW entry. */ 8458c2ecf20Sopenharmony_ci uint64_t tag_type:2; 8468c2ecf20Sopenharmony_ci /* The tag of the POW entry. */ 8478c2ecf20Sopenharmony_ci uint64_t tag:32; 8488c2ecf20Sopenharmony_ci#else 8498c2ecf20Sopenharmony_ci uint64_t tag:32; 8508c2ecf20Sopenharmony_ci uint64_t tag_type:2; 8518c2ecf20Sopenharmony_ci uint64_t tail:1; 8528c2ecf20Sopenharmony_ci uint64_t reserved_35:1; 8538c2ecf20Sopenharmony_ci uint64_t grp:4; 8548c2ecf20Sopenharmony_ci uint64_t next_index:11; 8558c2ecf20Sopenharmony_ci uint64_t reserved_51_63:13; 8568c2ecf20Sopenharmony_ci#endif 8578c2ecf20Sopenharmony_ci } s_smemload0; 8588c2ecf20Sopenharmony_ci 8598c2ecf20Sopenharmony_ci /** 8608c2ecf20Sopenharmony_ci * Result For POW Memory Load (get_des == 0 and get_wqp == 1) 8618c2ecf20Sopenharmony_ci */ 8628c2ecf20Sopenharmony_ci struct { 8638c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 8648c2ecf20Sopenharmony_ci uint64_t reserved_51_63:13; 8658c2ecf20Sopenharmony_ci /* 8668c2ecf20Sopenharmony_ci * The next entry in the input, free, descheduled_head 8678c2ecf20Sopenharmony_ci * list (unpredictable if entry is the tail of the 8688c2ecf20Sopenharmony_ci * list). 8698c2ecf20Sopenharmony_ci */ 8708c2ecf20Sopenharmony_ci uint64_t next_index:11; 8718c2ecf20Sopenharmony_ci /* The group of the POW entry. */ 8728c2ecf20Sopenharmony_ci uint64_t grp:4; 8738c2ecf20Sopenharmony_ci /* The WQP held in the POW entry. */ 8748c2ecf20Sopenharmony_ci uint64_t wqp:36; 8758c2ecf20Sopenharmony_ci#else 8768c2ecf20Sopenharmony_ci uint64_t wqp:36; 8778c2ecf20Sopenharmony_ci uint64_t grp:4; 8788c2ecf20Sopenharmony_ci uint64_t next_index:11; 8798c2ecf20Sopenharmony_ci uint64_t reserved_51_63:13; 8808c2ecf20Sopenharmony_ci#endif 8818c2ecf20Sopenharmony_ci } s_smemload1; 8828c2ecf20Sopenharmony_ci 8838c2ecf20Sopenharmony_ci /** 8848c2ecf20Sopenharmony_ci * Result For POW Memory Load (get_des == 1) 8858c2ecf20Sopenharmony_ci */ 8868c2ecf20Sopenharmony_ci struct { 8878c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 8888c2ecf20Sopenharmony_ci uint64_t reserved_51_63:13; 8898c2ecf20Sopenharmony_ci /* 8908c2ecf20Sopenharmony_ci * The next entry in the tag list connected to the 8918c2ecf20Sopenharmony_ci * descheduled head. 8928c2ecf20Sopenharmony_ci */ 8938c2ecf20Sopenharmony_ci uint64_t fwd_index:11; 8948c2ecf20Sopenharmony_ci /* The group of the POW entry. */ 8958c2ecf20Sopenharmony_ci uint64_t grp:4; 8968c2ecf20Sopenharmony_ci /* The nosched bit for the POW entry. */ 8978c2ecf20Sopenharmony_ci uint64_t nosched:1; 8988c2ecf20Sopenharmony_ci /* There is a pending tag switch */ 8998c2ecf20Sopenharmony_ci uint64_t pend_switch:1; 9008c2ecf20Sopenharmony_ci /* 9018c2ecf20Sopenharmony_ci * The next tag type for the new tag list when 9028c2ecf20Sopenharmony_ci * pend_switch is set. 9038c2ecf20Sopenharmony_ci */ 9048c2ecf20Sopenharmony_ci uint64_t pend_type:2; 9058c2ecf20Sopenharmony_ci /* 9068c2ecf20Sopenharmony_ci * The next tag for the new tag list when pend_switch 9078c2ecf20Sopenharmony_ci * is set. 9088c2ecf20Sopenharmony_ci */ 9098c2ecf20Sopenharmony_ci uint64_t pend_tag:32; 9108c2ecf20Sopenharmony_ci#else 9118c2ecf20Sopenharmony_ci uint64_t pend_tag:32; 9128c2ecf20Sopenharmony_ci uint64_t pend_type:2; 9138c2ecf20Sopenharmony_ci uint64_t pend_switch:1; 9148c2ecf20Sopenharmony_ci uint64_t nosched:1; 9158c2ecf20Sopenharmony_ci uint64_t grp:4; 9168c2ecf20Sopenharmony_ci uint64_t fwd_index:11; 9178c2ecf20Sopenharmony_ci uint64_t reserved_51_63:13; 9188c2ecf20Sopenharmony_ci#endif 9198c2ecf20Sopenharmony_ci } s_smemload2; 9208c2ecf20Sopenharmony_ci 9218c2ecf20Sopenharmony_ci /** 9228c2ecf20Sopenharmony_ci * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0) 9238c2ecf20Sopenharmony_ci */ 9248c2ecf20Sopenharmony_ci struct { 9258c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 9268c2ecf20Sopenharmony_ci uint64_t reserved_52_63:12; 9278c2ecf20Sopenharmony_ci /* 9288c2ecf20Sopenharmony_ci * set when there is one or more POW entries on the 9298c2ecf20Sopenharmony_ci * free list. 9308c2ecf20Sopenharmony_ci */ 9318c2ecf20Sopenharmony_ci uint64_t free_val:1; 9328c2ecf20Sopenharmony_ci /* 9338c2ecf20Sopenharmony_ci * set when there is exactly one POW entry on the free 9348c2ecf20Sopenharmony_ci * list. 9358c2ecf20Sopenharmony_ci */ 9368c2ecf20Sopenharmony_ci uint64_t free_one:1; 9378c2ecf20Sopenharmony_ci uint64_t reserved_49:1; 9388c2ecf20Sopenharmony_ci /* 9398c2ecf20Sopenharmony_ci * when free_val is set, indicates the first entry on 9408c2ecf20Sopenharmony_ci * the free list. 9418c2ecf20Sopenharmony_ci */ 9428c2ecf20Sopenharmony_ci uint64_t free_head:11; 9438c2ecf20Sopenharmony_ci uint64_t reserved_37:1; 9448c2ecf20Sopenharmony_ci /* 9458c2ecf20Sopenharmony_ci * when free_val is set, indicates the last entry on 9468c2ecf20Sopenharmony_ci * the free list. 9478c2ecf20Sopenharmony_ci */ 9488c2ecf20Sopenharmony_ci uint64_t free_tail:11; 9498c2ecf20Sopenharmony_ci /* 9508c2ecf20Sopenharmony_ci * set when there is one or more POW entries on the 9518c2ecf20Sopenharmony_ci * input Q list selected by qosgrp. 9528c2ecf20Sopenharmony_ci */ 9538c2ecf20Sopenharmony_ci uint64_t loc_val:1; 9548c2ecf20Sopenharmony_ci /* 9558c2ecf20Sopenharmony_ci * set when there is exactly one POW entry on the 9568c2ecf20Sopenharmony_ci * input Q list selected by qosgrp. 9578c2ecf20Sopenharmony_ci */ 9588c2ecf20Sopenharmony_ci uint64_t loc_one:1; 9598c2ecf20Sopenharmony_ci uint64_t reserved_23:1; 9608c2ecf20Sopenharmony_ci /* 9618c2ecf20Sopenharmony_ci * when loc_val is set, indicates the first entry on 9628c2ecf20Sopenharmony_ci * the input Q list selected by qosgrp. 9638c2ecf20Sopenharmony_ci */ 9648c2ecf20Sopenharmony_ci uint64_t loc_head:11; 9658c2ecf20Sopenharmony_ci uint64_t reserved_11:1; 9668c2ecf20Sopenharmony_ci /* 9678c2ecf20Sopenharmony_ci * when loc_val is set, indicates the last entry on 9688c2ecf20Sopenharmony_ci * the input Q list selected by qosgrp. 9698c2ecf20Sopenharmony_ci */ 9708c2ecf20Sopenharmony_ci uint64_t loc_tail:11; 9718c2ecf20Sopenharmony_ci#else 9728c2ecf20Sopenharmony_ci uint64_t loc_tail:11; 9738c2ecf20Sopenharmony_ci uint64_t reserved_11:1; 9748c2ecf20Sopenharmony_ci uint64_t loc_head:11; 9758c2ecf20Sopenharmony_ci uint64_t reserved_23:1; 9768c2ecf20Sopenharmony_ci uint64_t loc_one:1; 9778c2ecf20Sopenharmony_ci uint64_t loc_val:1; 9788c2ecf20Sopenharmony_ci uint64_t free_tail:11; 9798c2ecf20Sopenharmony_ci uint64_t reserved_37:1; 9808c2ecf20Sopenharmony_ci uint64_t free_head:11; 9818c2ecf20Sopenharmony_ci uint64_t reserved_49:1; 9828c2ecf20Sopenharmony_ci uint64_t free_one:1; 9838c2ecf20Sopenharmony_ci uint64_t free_val:1; 9848c2ecf20Sopenharmony_ci uint64_t reserved_52_63:12; 9858c2ecf20Sopenharmony_ci#endif 9868c2ecf20Sopenharmony_ci } sindexload0; 9878c2ecf20Sopenharmony_ci 9888c2ecf20Sopenharmony_ci /** 9898c2ecf20Sopenharmony_ci * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1) 9908c2ecf20Sopenharmony_ci */ 9918c2ecf20Sopenharmony_ci struct { 9928c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 9938c2ecf20Sopenharmony_ci uint64_t reserved_52_63:12; 9948c2ecf20Sopenharmony_ci /* 9958c2ecf20Sopenharmony_ci * set when there is one or more POW entries on the 9968c2ecf20Sopenharmony_ci * nosched list. 9978c2ecf20Sopenharmony_ci */ 9988c2ecf20Sopenharmony_ci uint64_t nosched_val:1; 9998c2ecf20Sopenharmony_ci /* 10008c2ecf20Sopenharmony_ci * set when there is exactly one POW entry on the 10018c2ecf20Sopenharmony_ci * nosched list. 10028c2ecf20Sopenharmony_ci */ 10038c2ecf20Sopenharmony_ci uint64_t nosched_one:1; 10048c2ecf20Sopenharmony_ci uint64_t reserved_49:1; 10058c2ecf20Sopenharmony_ci /* 10068c2ecf20Sopenharmony_ci * when nosched_val is set, indicates the first entry 10078c2ecf20Sopenharmony_ci * on the nosched list. 10088c2ecf20Sopenharmony_ci */ 10098c2ecf20Sopenharmony_ci uint64_t nosched_head:11; 10108c2ecf20Sopenharmony_ci uint64_t reserved_37:1; 10118c2ecf20Sopenharmony_ci /* 10128c2ecf20Sopenharmony_ci * when nosched_val is set, indicates the last entry 10138c2ecf20Sopenharmony_ci * on the nosched list. 10148c2ecf20Sopenharmony_ci */ 10158c2ecf20Sopenharmony_ci uint64_t nosched_tail:11; 10168c2ecf20Sopenharmony_ci /* 10178c2ecf20Sopenharmony_ci * set when there is one or more descheduled heads on 10188c2ecf20Sopenharmony_ci * the descheduled list selected by qosgrp. 10198c2ecf20Sopenharmony_ci */ 10208c2ecf20Sopenharmony_ci uint64_t des_val:1; 10218c2ecf20Sopenharmony_ci /* 10228c2ecf20Sopenharmony_ci * set when there is exactly one descheduled head on 10238c2ecf20Sopenharmony_ci * the descheduled list selected by qosgrp. 10248c2ecf20Sopenharmony_ci */ 10258c2ecf20Sopenharmony_ci uint64_t des_one:1; 10268c2ecf20Sopenharmony_ci uint64_t reserved_23:1; 10278c2ecf20Sopenharmony_ci /* 10288c2ecf20Sopenharmony_ci * when des_val is set, indicates the first 10298c2ecf20Sopenharmony_ci * descheduled head on the descheduled list selected 10308c2ecf20Sopenharmony_ci * by qosgrp. 10318c2ecf20Sopenharmony_ci */ 10328c2ecf20Sopenharmony_ci uint64_t des_head:11; 10338c2ecf20Sopenharmony_ci uint64_t reserved_11:1; 10348c2ecf20Sopenharmony_ci /* 10358c2ecf20Sopenharmony_ci * when des_val is set, indicates the last descheduled 10368c2ecf20Sopenharmony_ci * head on the descheduled list selected by qosgrp. 10378c2ecf20Sopenharmony_ci */ 10388c2ecf20Sopenharmony_ci uint64_t des_tail:11; 10398c2ecf20Sopenharmony_ci#else 10408c2ecf20Sopenharmony_ci uint64_t des_tail:11; 10418c2ecf20Sopenharmony_ci uint64_t reserved_11:1; 10428c2ecf20Sopenharmony_ci uint64_t des_head:11; 10438c2ecf20Sopenharmony_ci uint64_t reserved_23:1; 10448c2ecf20Sopenharmony_ci uint64_t des_one:1; 10458c2ecf20Sopenharmony_ci uint64_t des_val:1; 10468c2ecf20Sopenharmony_ci uint64_t nosched_tail:11; 10478c2ecf20Sopenharmony_ci uint64_t reserved_37:1; 10488c2ecf20Sopenharmony_ci uint64_t nosched_head:11; 10498c2ecf20Sopenharmony_ci uint64_t reserved_49:1; 10508c2ecf20Sopenharmony_ci uint64_t nosched_one:1; 10518c2ecf20Sopenharmony_ci uint64_t nosched_val:1; 10528c2ecf20Sopenharmony_ci uint64_t reserved_52_63:12; 10538c2ecf20Sopenharmony_ci#endif 10548c2ecf20Sopenharmony_ci } sindexload1; 10558c2ecf20Sopenharmony_ci 10568c2ecf20Sopenharmony_ci /** 10578c2ecf20Sopenharmony_ci * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0) 10588c2ecf20Sopenharmony_ci */ 10598c2ecf20Sopenharmony_ci struct { 10608c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 10618c2ecf20Sopenharmony_ci uint64_t reserved_39_63:25; 10628c2ecf20Sopenharmony_ci /* 10638c2ecf20Sopenharmony_ci * Set when this DRAM list is the current head 10648c2ecf20Sopenharmony_ci * (i.e. is the next to be reloaded when the POW 10658c2ecf20Sopenharmony_ci * hardware reloads a POW entry from DRAM). The POW 10668c2ecf20Sopenharmony_ci * hardware alternates between the two DRAM lists 10678c2ecf20Sopenharmony_ci * associated with a QOS level when it reloads work 10688c2ecf20Sopenharmony_ci * from DRAM into the POW unit. 10698c2ecf20Sopenharmony_ci */ 10708c2ecf20Sopenharmony_ci uint64_t rmt_is_head:1; 10718c2ecf20Sopenharmony_ci /* 10728c2ecf20Sopenharmony_ci * Set when the DRAM portion of the input Q list 10738c2ecf20Sopenharmony_ci * selected by qosgrp contains one or more pieces of 10748c2ecf20Sopenharmony_ci * work. 10758c2ecf20Sopenharmony_ci */ 10768c2ecf20Sopenharmony_ci uint64_t rmt_val:1; 10778c2ecf20Sopenharmony_ci /* 10788c2ecf20Sopenharmony_ci * Set when the DRAM portion of the input Q list 10798c2ecf20Sopenharmony_ci * selected by qosgrp contains exactly one piece of 10808c2ecf20Sopenharmony_ci * work. 10818c2ecf20Sopenharmony_ci */ 10828c2ecf20Sopenharmony_ci uint64_t rmt_one:1; 10838c2ecf20Sopenharmony_ci /* 10848c2ecf20Sopenharmony_ci * When rmt_val is set, indicates the first piece of 10858c2ecf20Sopenharmony_ci * work on the DRAM input Q list selected by 10868c2ecf20Sopenharmony_ci * qosgrp. 10878c2ecf20Sopenharmony_ci */ 10888c2ecf20Sopenharmony_ci uint64_t rmt_head:36; 10898c2ecf20Sopenharmony_ci#else 10908c2ecf20Sopenharmony_ci uint64_t rmt_head:36; 10918c2ecf20Sopenharmony_ci uint64_t rmt_one:1; 10928c2ecf20Sopenharmony_ci uint64_t rmt_val:1; 10938c2ecf20Sopenharmony_ci uint64_t rmt_is_head:1; 10948c2ecf20Sopenharmony_ci uint64_t reserved_39_63:25; 10958c2ecf20Sopenharmony_ci#endif 10968c2ecf20Sopenharmony_ci } sindexload2; 10978c2ecf20Sopenharmony_ci 10988c2ecf20Sopenharmony_ci /** 10998c2ecf20Sopenharmony_ci * Result For POW Index/Pointer Load (get_rmt == 11008c2ecf20Sopenharmony_ci * 1/get_des_get_tail == 1) 11018c2ecf20Sopenharmony_ci */ 11028c2ecf20Sopenharmony_ci struct { 11038c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 11048c2ecf20Sopenharmony_ci uint64_t reserved_39_63:25; 11058c2ecf20Sopenharmony_ci /* 11068c2ecf20Sopenharmony_ci * set when this DRAM list is the current head 11078c2ecf20Sopenharmony_ci * (i.e. is the next to be reloaded when the POW 11088c2ecf20Sopenharmony_ci * hardware reloads a POW entry from DRAM). The POW 11098c2ecf20Sopenharmony_ci * hardware alternates between the two DRAM lists 11108c2ecf20Sopenharmony_ci * associated with a QOS level when it reloads work 11118c2ecf20Sopenharmony_ci * from DRAM into the POW unit. 11128c2ecf20Sopenharmony_ci */ 11138c2ecf20Sopenharmony_ci uint64_t rmt_is_head:1; 11148c2ecf20Sopenharmony_ci /* 11158c2ecf20Sopenharmony_ci * set when the DRAM portion of the input Q list 11168c2ecf20Sopenharmony_ci * selected by qosgrp contains one or more pieces of 11178c2ecf20Sopenharmony_ci * work. 11188c2ecf20Sopenharmony_ci */ 11198c2ecf20Sopenharmony_ci uint64_t rmt_val:1; 11208c2ecf20Sopenharmony_ci /* 11218c2ecf20Sopenharmony_ci * set when the DRAM portion of the input Q list 11228c2ecf20Sopenharmony_ci * selected by qosgrp contains exactly one piece of 11238c2ecf20Sopenharmony_ci * work. 11248c2ecf20Sopenharmony_ci */ 11258c2ecf20Sopenharmony_ci uint64_t rmt_one:1; 11268c2ecf20Sopenharmony_ci /* 11278c2ecf20Sopenharmony_ci * when rmt_val is set, indicates the last piece of 11288c2ecf20Sopenharmony_ci * work on the DRAM input Q list selected by 11298c2ecf20Sopenharmony_ci * qosgrp. 11308c2ecf20Sopenharmony_ci */ 11318c2ecf20Sopenharmony_ci uint64_t rmt_tail:36; 11328c2ecf20Sopenharmony_ci#else 11338c2ecf20Sopenharmony_ci uint64_t rmt_tail:36; 11348c2ecf20Sopenharmony_ci uint64_t rmt_one:1; 11358c2ecf20Sopenharmony_ci uint64_t rmt_val:1; 11368c2ecf20Sopenharmony_ci uint64_t rmt_is_head:1; 11378c2ecf20Sopenharmony_ci uint64_t reserved_39_63:25; 11388c2ecf20Sopenharmony_ci#endif 11398c2ecf20Sopenharmony_ci } sindexload3; 11408c2ecf20Sopenharmony_ci 11418c2ecf20Sopenharmony_ci /** 11428c2ecf20Sopenharmony_ci * Response to NULL_RD request loads 11438c2ecf20Sopenharmony_ci */ 11448c2ecf20Sopenharmony_ci struct { 11458c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 11468c2ecf20Sopenharmony_ci uint64_t unused:62; 11478c2ecf20Sopenharmony_ci /* of type cvmx_pow_tag_type_t. state is one of the 11488c2ecf20Sopenharmony_ci * following: 11498c2ecf20Sopenharmony_ci * 11508c2ecf20Sopenharmony_ci * - CVMX_POW_TAG_TYPE_ORDERED 11518c2ecf20Sopenharmony_ci * - CVMX_POW_TAG_TYPE_ATOMIC 11528c2ecf20Sopenharmony_ci * - CVMX_POW_TAG_TYPE_NULL 11538c2ecf20Sopenharmony_ci * - CVMX_POW_TAG_TYPE_NULL_NULL 11548c2ecf20Sopenharmony_ci */ 11558c2ecf20Sopenharmony_ci uint64_t state:2; 11568c2ecf20Sopenharmony_ci#else 11578c2ecf20Sopenharmony_ci uint64_t state:2; 11588c2ecf20Sopenharmony_ci uint64_t unused:62; 11598c2ecf20Sopenharmony_ci#endif 11608c2ecf20Sopenharmony_ci } s_null_rd; 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci} cvmx_pow_tag_load_resp_t; 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_ci/** 11658c2ecf20Sopenharmony_ci * This structure describes the address used for stores to the POW. 11668c2ecf20Sopenharmony_ci * The store address is meaningful on stores to the POW. The 11678c2ecf20Sopenharmony_ci * hardware assumes that an aligned 64-bit store was used for all 11688c2ecf20Sopenharmony_ci * these stores. Note the assumption that the work queue entry is 11698c2ecf20Sopenharmony_ci * aligned on an 8-byte boundary (since the low-order 3 address bits 11708c2ecf20Sopenharmony_ci * must be zero). Note that not all fields are used by all 11718c2ecf20Sopenharmony_ci * operations. 11728c2ecf20Sopenharmony_ci * 11738c2ecf20Sopenharmony_ci * NOTE: The following is the behavior of the pending switch bit at the PP 11748c2ecf20Sopenharmony_ci * for POW stores (i.e. when did<7:3> == 0xc) 11758c2ecf20Sopenharmony_ci * - did<2:0> == 0 => pending switch bit is set 11768c2ecf20Sopenharmony_ci * - did<2:0> == 1 => no affect on the pending switch bit 11778c2ecf20Sopenharmony_ci * - did<2:0> == 3 => pending switch bit is cleared 11788c2ecf20Sopenharmony_ci * - did<2:0> == 7 => no affect on the pending switch bit 11798c2ecf20Sopenharmony_ci * - did<2:0> == others => must not be used 11808c2ecf20Sopenharmony_ci * - No other loads/stores have an affect on the pending switch bit 11818c2ecf20Sopenharmony_ci * - The switch bus from POW can clear the pending switch bit 11828c2ecf20Sopenharmony_ci * 11838c2ecf20Sopenharmony_ci * NOTE: did<2:0> == 2 is used by the HW for a special single-cycle 11848c2ecf20Sopenharmony_ci * ADDWQ command that only contains the pointer). SW must never use 11858c2ecf20Sopenharmony_ci * did<2:0> == 2. 11868c2ecf20Sopenharmony_ci */ 11878c2ecf20Sopenharmony_citypedef union { 11888c2ecf20Sopenharmony_ci /** 11898c2ecf20Sopenharmony_ci * Unsigned 64 bit integer representation of store address 11908c2ecf20Sopenharmony_ci */ 11918c2ecf20Sopenharmony_ci uint64_t u64; 11928c2ecf20Sopenharmony_ci 11938c2ecf20Sopenharmony_ci struct { 11948c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 11958c2ecf20Sopenharmony_ci /* Memory region. Should be CVMX_IO_SEG in most cases */ 11968c2ecf20Sopenharmony_ci uint64_t mem_reg:2; 11978c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; /* Must be zero */ 11988c2ecf20Sopenharmony_ci uint64_t is_io:1; /* Must be one */ 11998c2ecf20Sopenharmony_ci /* Device ID of POW. Note that different sub-dids are used. */ 12008c2ecf20Sopenharmony_ci uint64_t did:8; 12018c2ecf20Sopenharmony_ci uint64_t reserved_36_39:4; /* Must be zero */ 12028c2ecf20Sopenharmony_ci /* Address field. addr<2:0> must be zero */ 12038c2ecf20Sopenharmony_ci uint64_t addr:36; 12048c2ecf20Sopenharmony_ci#else 12058c2ecf20Sopenharmony_ci uint64_t addr:36; 12068c2ecf20Sopenharmony_ci uint64_t reserved_36_39:4; 12078c2ecf20Sopenharmony_ci uint64_t did:8; 12088c2ecf20Sopenharmony_ci uint64_t is_io:1; 12098c2ecf20Sopenharmony_ci uint64_t reserved_49_61:13; 12108c2ecf20Sopenharmony_ci uint64_t mem_reg:2; 12118c2ecf20Sopenharmony_ci#endif 12128c2ecf20Sopenharmony_ci } stag; 12138c2ecf20Sopenharmony_ci} cvmx_pow_tag_store_addr_t; 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_ci/** 12168c2ecf20Sopenharmony_ci * decode of the store data when an IOBDMA SENDSINGLE is sent to POW 12178c2ecf20Sopenharmony_ci */ 12188c2ecf20Sopenharmony_citypedef union { 12198c2ecf20Sopenharmony_ci uint64_t u64; 12208c2ecf20Sopenharmony_ci 12218c2ecf20Sopenharmony_ci struct { 12228c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 12238c2ecf20Sopenharmony_ci /* 12248c2ecf20Sopenharmony_ci * the (64-bit word) location in scratchpad to write 12258c2ecf20Sopenharmony_ci * to (if len != 0) 12268c2ecf20Sopenharmony_ci */ 12278c2ecf20Sopenharmony_ci uint64_t scraddr:8; 12288c2ecf20Sopenharmony_ci /* the number of words in the response (0 => no response) */ 12298c2ecf20Sopenharmony_ci uint64_t len:8; 12308c2ecf20Sopenharmony_ci /* the ID of the device on the non-coherent bus */ 12318c2ecf20Sopenharmony_ci uint64_t did:8; 12328c2ecf20Sopenharmony_ci uint64_t unused:36; 12338c2ecf20Sopenharmony_ci /* if set, don't return load response until work is available */ 12348c2ecf20Sopenharmony_ci uint64_t wait:1; 12358c2ecf20Sopenharmony_ci uint64_t unused2:3; 12368c2ecf20Sopenharmony_ci#else 12378c2ecf20Sopenharmony_ci uint64_t unused2:3; 12388c2ecf20Sopenharmony_ci uint64_t wait:1; 12398c2ecf20Sopenharmony_ci uint64_t unused:36; 12408c2ecf20Sopenharmony_ci uint64_t did:8; 12418c2ecf20Sopenharmony_ci uint64_t len:8; 12428c2ecf20Sopenharmony_ci uint64_t scraddr:8; 12438c2ecf20Sopenharmony_ci#endif 12448c2ecf20Sopenharmony_ci } s; 12458c2ecf20Sopenharmony_ci 12468c2ecf20Sopenharmony_ci} cvmx_pow_iobdma_store_t; 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_ci/* CSR typedefs have been moved to cvmx-csr-*.h */ 12498c2ecf20Sopenharmony_ci 12508c2ecf20Sopenharmony_ci/** 12518c2ecf20Sopenharmony_ci * Get the POW tag for this core. This returns the current 12528c2ecf20Sopenharmony_ci * tag type, tag, group, and POW entry index associated with 12538c2ecf20Sopenharmony_ci * this core. Index is only valid if the tag type isn't NULL_NULL. 12548c2ecf20Sopenharmony_ci * If a tag switch is pending this routine returns the tag before 12558c2ecf20Sopenharmony_ci * the tag switch, not after. 12568c2ecf20Sopenharmony_ci * 12578c2ecf20Sopenharmony_ci * Returns Current tag 12588c2ecf20Sopenharmony_ci */ 12598c2ecf20Sopenharmony_cistatic inline cvmx_pow_tag_req_t cvmx_pow_get_current_tag(void) 12608c2ecf20Sopenharmony_ci{ 12618c2ecf20Sopenharmony_ci cvmx_pow_load_addr_t load_addr; 12628c2ecf20Sopenharmony_ci cvmx_pow_tag_load_resp_t load_resp; 12638c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t result; 12648c2ecf20Sopenharmony_ci 12658c2ecf20Sopenharmony_ci load_addr.u64 = 0; 12668c2ecf20Sopenharmony_ci load_addr.sstatus.mem_region = CVMX_IO_SEG; 12678c2ecf20Sopenharmony_ci load_addr.sstatus.is_io = 1; 12688c2ecf20Sopenharmony_ci load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1; 12698c2ecf20Sopenharmony_ci load_addr.sstatus.coreid = cvmx_get_core_num(); 12708c2ecf20Sopenharmony_ci load_addr.sstatus.get_cur = 1; 12718c2ecf20Sopenharmony_ci load_resp.u64 = cvmx_read_csr(load_addr.u64); 12728c2ecf20Sopenharmony_ci result.u64 = 0; 12738c2ecf20Sopenharmony_ci result.s.grp = load_resp.s_sstatus2.grp; 12748c2ecf20Sopenharmony_ci result.s.index = load_resp.s_sstatus2.index; 12758c2ecf20Sopenharmony_ci result.s.type = load_resp.s_sstatus2.tag_type; 12768c2ecf20Sopenharmony_ci result.s.tag = load_resp.s_sstatus2.tag; 12778c2ecf20Sopenharmony_ci return result; 12788c2ecf20Sopenharmony_ci} 12798c2ecf20Sopenharmony_ci 12808c2ecf20Sopenharmony_ci/** 12818c2ecf20Sopenharmony_ci * Get the POW WQE for this core. This returns the work queue 12828c2ecf20Sopenharmony_ci * entry currently associated with this core. 12838c2ecf20Sopenharmony_ci * 12848c2ecf20Sopenharmony_ci * Returns WQE pointer 12858c2ecf20Sopenharmony_ci */ 12868c2ecf20Sopenharmony_cistatic inline struct cvmx_wqe *cvmx_pow_get_current_wqp(void) 12878c2ecf20Sopenharmony_ci{ 12888c2ecf20Sopenharmony_ci cvmx_pow_load_addr_t load_addr; 12898c2ecf20Sopenharmony_ci cvmx_pow_tag_load_resp_t load_resp; 12908c2ecf20Sopenharmony_ci 12918c2ecf20Sopenharmony_ci load_addr.u64 = 0; 12928c2ecf20Sopenharmony_ci load_addr.sstatus.mem_region = CVMX_IO_SEG; 12938c2ecf20Sopenharmony_ci load_addr.sstatus.is_io = 1; 12948c2ecf20Sopenharmony_ci load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1; 12958c2ecf20Sopenharmony_ci load_addr.sstatus.coreid = cvmx_get_core_num(); 12968c2ecf20Sopenharmony_ci load_addr.sstatus.get_cur = 1; 12978c2ecf20Sopenharmony_ci load_addr.sstatus.get_wqp = 1; 12988c2ecf20Sopenharmony_ci load_resp.u64 = cvmx_read_csr(load_addr.u64); 12998c2ecf20Sopenharmony_ci return (struct cvmx_wqe *) cvmx_phys_to_ptr(load_resp.s_sstatus4.wqp); 13008c2ecf20Sopenharmony_ci} 13018c2ecf20Sopenharmony_ci 13028c2ecf20Sopenharmony_ci#ifndef CVMX_MF_CHORD 13038c2ecf20Sopenharmony_ci#define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30) 13048c2ecf20Sopenharmony_ci#endif 13058c2ecf20Sopenharmony_ci 13068c2ecf20Sopenharmony_ci/** 13078c2ecf20Sopenharmony_ci * Print a warning if a tag switch is pending for this core 13088c2ecf20Sopenharmony_ci * 13098c2ecf20Sopenharmony_ci * @function: Function name checking for a pending tag switch 13108c2ecf20Sopenharmony_ci */ 13118c2ecf20Sopenharmony_cistatic inline void __cvmx_pow_warn_if_pending_switch(const char *function) 13128c2ecf20Sopenharmony_ci{ 13138c2ecf20Sopenharmony_ci uint64_t switch_complete; 13148c2ecf20Sopenharmony_ci CVMX_MF_CHORD(switch_complete); 13158c2ecf20Sopenharmony_ci if (!switch_complete) 13168c2ecf20Sopenharmony_ci pr_warn("%s called with tag switch in progress\n", function); 13178c2ecf20Sopenharmony_ci} 13188c2ecf20Sopenharmony_ci 13198c2ecf20Sopenharmony_ci/** 13208c2ecf20Sopenharmony_ci * Waits for a tag switch to complete by polling the completion bit. 13218c2ecf20Sopenharmony_ci * Note that switches to NULL complete immediately and do not need 13228c2ecf20Sopenharmony_ci * to be waited for. 13238c2ecf20Sopenharmony_ci */ 13248c2ecf20Sopenharmony_cistatic inline void cvmx_pow_tag_sw_wait(void) 13258c2ecf20Sopenharmony_ci{ 13268c2ecf20Sopenharmony_ci const uint64_t MAX_CYCLES = 1ull << 31; 13278c2ecf20Sopenharmony_ci uint64_t switch_complete; 13288c2ecf20Sopenharmony_ci uint64_t start_cycle = cvmx_get_cycle(); 13298c2ecf20Sopenharmony_ci while (1) { 13308c2ecf20Sopenharmony_ci CVMX_MF_CHORD(switch_complete); 13318c2ecf20Sopenharmony_ci if (unlikely(switch_complete)) 13328c2ecf20Sopenharmony_ci break; 13338c2ecf20Sopenharmony_ci if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { 13348c2ecf20Sopenharmony_ci pr_warn("Tag switch is taking a long time, possible deadlock\n"); 13358c2ecf20Sopenharmony_ci start_cycle = -MAX_CYCLES - 1; 13368c2ecf20Sopenharmony_ci } 13378c2ecf20Sopenharmony_ci } 13388c2ecf20Sopenharmony_ci} 13398c2ecf20Sopenharmony_ci 13408c2ecf20Sopenharmony_ci/** 13418c2ecf20Sopenharmony_ci * Synchronous work request. Requests work from the POW. 13428c2ecf20Sopenharmony_ci * This function does NOT wait for previous tag switches to complete, 13438c2ecf20Sopenharmony_ci * so the caller must ensure that there is not a pending tag switch. 13448c2ecf20Sopenharmony_ci * 13458c2ecf20Sopenharmony_ci * @wait: When set, call stalls until work becomes avaiable, or times out. 13468c2ecf20Sopenharmony_ci * If not set, returns immediately. 13478c2ecf20Sopenharmony_ci * 13488c2ecf20Sopenharmony_ci * Returns: the WQE pointer from POW. Returns NULL if no work 13498c2ecf20Sopenharmony_ci * was available. 13508c2ecf20Sopenharmony_ci */ 13518c2ecf20Sopenharmony_cistatic inline struct cvmx_wqe *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t 13528c2ecf20Sopenharmony_ci wait) 13538c2ecf20Sopenharmony_ci{ 13548c2ecf20Sopenharmony_ci cvmx_pow_load_addr_t ptr; 13558c2ecf20Sopenharmony_ci cvmx_pow_tag_load_resp_t result; 13568c2ecf20Sopenharmony_ci 13578c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 13588c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 13598c2ecf20Sopenharmony_ci 13608c2ecf20Sopenharmony_ci ptr.u64 = 0; 13618c2ecf20Sopenharmony_ci ptr.swork.mem_region = CVMX_IO_SEG; 13628c2ecf20Sopenharmony_ci ptr.swork.is_io = 1; 13638c2ecf20Sopenharmony_ci ptr.swork.did = CVMX_OCT_DID_TAG_SWTAG; 13648c2ecf20Sopenharmony_ci ptr.swork.wait = wait; 13658c2ecf20Sopenharmony_ci 13668c2ecf20Sopenharmony_ci result.u64 = cvmx_read_csr(ptr.u64); 13678c2ecf20Sopenharmony_ci 13688c2ecf20Sopenharmony_ci if (result.s_work.no_work) 13698c2ecf20Sopenharmony_ci return NULL; 13708c2ecf20Sopenharmony_ci else 13718c2ecf20Sopenharmony_ci return (struct cvmx_wqe *) cvmx_phys_to_ptr(result.s_work.addr); 13728c2ecf20Sopenharmony_ci} 13738c2ecf20Sopenharmony_ci 13748c2ecf20Sopenharmony_ci/** 13758c2ecf20Sopenharmony_ci * Synchronous work request. Requests work from the POW. 13768c2ecf20Sopenharmony_ci * This function waits for any previous tag switch to complete before 13778c2ecf20Sopenharmony_ci * requesting the new work. 13788c2ecf20Sopenharmony_ci * 13798c2ecf20Sopenharmony_ci * @wait: When set, call stalls until work becomes avaiable, or times out. 13808c2ecf20Sopenharmony_ci * If not set, returns immediately. 13818c2ecf20Sopenharmony_ci * 13828c2ecf20Sopenharmony_ci * Returns: the WQE pointer from POW. Returns NULL if no work 13838c2ecf20Sopenharmony_ci * was available. 13848c2ecf20Sopenharmony_ci */ 13858c2ecf20Sopenharmony_cistatic inline struct cvmx_wqe *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait) 13868c2ecf20Sopenharmony_ci{ 13878c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 13888c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 13898c2ecf20Sopenharmony_ci 13908c2ecf20Sopenharmony_ci /* Must not have a switch pending when requesting work */ 13918c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_wait(); 13928c2ecf20Sopenharmony_ci return cvmx_pow_work_request_sync_nocheck(wait); 13938c2ecf20Sopenharmony_ci 13948c2ecf20Sopenharmony_ci} 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_ci/** 13978c2ecf20Sopenharmony_ci * Synchronous null_rd request. Requests a switch out of NULL_NULL POW state. 13988c2ecf20Sopenharmony_ci * This function waits for any previous tag switch to complete before 13998c2ecf20Sopenharmony_ci * requesting the null_rd. 14008c2ecf20Sopenharmony_ci * 14018c2ecf20Sopenharmony_ci * Returns: the POW state of type cvmx_pow_tag_type_t. 14028c2ecf20Sopenharmony_ci */ 14038c2ecf20Sopenharmony_cistatic inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void) 14048c2ecf20Sopenharmony_ci{ 14058c2ecf20Sopenharmony_ci cvmx_pow_load_addr_t ptr; 14068c2ecf20Sopenharmony_ci cvmx_pow_tag_load_resp_t result; 14078c2ecf20Sopenharmony_ci 14088c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 14098c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 14108c2ecf20Sopenharmony_ci 14118c2ecf20Sopenharmony_ci /* Must not have a switch pending when requesting work */ 14128c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_wait(); 14138c2ecf20Sopenharmony_ci 14148c2ecf20Sopenharmony_ci ptr.u64 = 0; 14158c2ecf20Sopenharmony_ci ptr.snull_rd.mem_region = CVMX_IO_SEG; 14168c2ecf20Sopenharmony_ci ptr.snull_rd.is_io = 1; 14178c2ecf20Sopenharmony_ci ptr.snull_rd.did = CVMX_OCT_DID_TAG_NULL_RD; 14188c2ecf20Sopenharmony_ci 14198c2ecf20Sopenharmony_ci result.u64 = cvmx_read_csr(ptr.u64); 14208c2ecf20Sopenharmony_ci 14218c2ecf20Sopenharmony_ci return (enum cvmx_pow_tag_type) result.s_null_rd.state; 14228c2ecf20Sopenharmony_ci} 14238c2ecf20Sopenharmony_ci 14248c2ecf20Sopenharmony_ci/** 14258c2ecf20Sopenharmony_ci * Asynchronous work request. Work is requested from the POW unit, 14268c2ecf20Sopenharmony_ci * and should later be checked with function 14278c2ecf20Sopenharmony_ci * cvmx_pow_work_response_async. This function does NOT wait for 14288c2ecf20Sopenharmony_ci * previous tag switches to complete, so the caller must ensure that 14298c2ecf20Sopenharmony_ci * there is not a pending tag switch. 14308c2ecf20Sopenharmony_ci * 14318c2ecf20Sopenharmony_ci * @scr_addr: Scratch memory address that response will be returned 14328c2ecf20Sopenharmony_ci * to, which is either a valid WQE, or a response with the 14338c2ecf20Sopenharmony_ci * invalid bit set. Byte address, must be 8 byte aligned. 14348c2ecf20Sopenharmony_ci * 14358c2ecf20Sopenharmony_ci * @wait: 1 to cause response to wait for work to become available (or 14368c2ecf20Sopenharmony_ci * timeout), 0 to cause response to return immediately 14378c2ecf20Sopenharmony_ci */ 14388c2ecf20Sopenharmony_cistatic inline void cvmx_pow_work_request_async_nocheck(int scr_addr, 14398c2ecf20Sopenharmony_ci cvmx_pow_wait_t wait) 14408c2ecf20Sopenharmony_ci{ 14418c2ecf20Sopenharmony_ci cvmx_pow_iobdma_store_t data; 14428c2ecf20Sopenharmony_ci 14438c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 14448c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_ci /* scr_addr must be 8 byte aligned */ 14478c2ecf20Sopenharmony_ci data.s.scraddr = scr_addr >> 3; 14488c2ecf20Sopenharmony_ci data.s.len = 1; 14498c2ecf20Sopenharmony_ci data.s.did = CVMX_OCT_DID_TAG_SWTAG; 14508c2ecf20Sopenharmony_ci data.s.wait = wait; 14518c2ecf20Sopenharmony_ci cvmx_send_single(data.u64); 14528c2ecf20Sopenharmony_ci} 14538c2ecf20Sopenharmony_ci 14548c2ecf20Sopenharmony_ci/** 14558c2ecf20Sopenharmony_ci * Asynchronous work request. Work is requested from the POW unit, 14568c2ecf20Sopenharmony_ci * and should later be checked with function 14578c2ecf20Sopenharmony_ci * cvmx_pow_work_response_async. This function waits for any previous 14588c2ecf20Sopenharmony_ci * tag switch to complete before requesting the new work. 14598c2ecf20Sopenharmony_ci * 14608c2ecf20Sopenharmony_ci * @scr_addr: Scratch memory address that response will be returned 14618c2ecf20Sopenharmony_ci * to, which is either a valid WQE, or a response with the 14628c2ecf20Sopenharmony_ci * invalid bit set. Byte address, must be 8 byte aligned. 14638c2ecf20Sopenharmony_ci * 14648c2ecf20Sopenharmony_ci * @wait: 1 to cause response to wait for work to become available (or 14658c2ecf20Sopenharmony_ci * timeout), 0 to cause response to return immediately 14668c2ecf20Sopenharmony_ci */ 14678c2ecf20Sopenharmony_cistatic inline void cvmx_pow_work_request_async(int scr_addr, 14688c2ecf20Sopenharmony_ci cvmx_pow_wait_t wait) 14698c2ecf20Sopenharmony_ci{ 14708c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 14718c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 14728c2ecf20Sopenharmony_ci 14738c2ecf20Sopenharmony_ci /* Must not have a switch pending when requesting work */ 14748c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_wait(); 14758c2ecf20Sopenharmony_ci cvmx_pow_work_request_async_nocheck(scr_addr, wait); 14768c2ecf20Sopenharmony_ci} 14778c2ecf20Sopenharmony_ci 14788c2ecf20Sopenharmony_ci/** 14798c2ecf20Sopenharmony_ci * Gets result of asynchronous work request. Performs a IOBDMA sync 14808c2ecf20Sopenharmony_ci * to wait for the response. 14818c2ecf20Sopenharmony_ci * 14828c2ecf20Sopenharmony_ci * @scr_addr: Scratch memory address to get result from Byte address, 14838c2ecf20Sopenharmony_ci * must be 8 byte aligned. 14848c2ecf20Sopenharmony_ci * 14858c2ecf20Sopenharmony_ci * Returns: the WQE from the scratch register, or NULL if no 14868c2ecf20Sopenharmony_ci * work was available. 14878c2ecf20Sopenharmony_ci */ 14888c2ecf20Sopenharmony_cistatic inline struct cvmx_wqe *cvmx_pow_work_response_async(int scr_addr) 14898c2ecf20Sopenharmony_ci{ 14908c2ecf20Sopenharmony_ci cvmx_pow_tag_load_resp_t result; 14918c2ecf20Sopenharmony_ci 14928c2ecf20Sopenharmony_ci CVMX_SYNCIOBDMA; 14938c2ecf20Sopenharmony_ci result.u64 = cvmx_scratch_read64(scr_addr); 14948c2ecf20Sopenharmony_ci 14958c2ecf20Sopenharmony_ci if (result.s_work.no_work) 14968c2ecf20Sopenharmony_ci return NULL; 14978c2ecf20Sopenharmony_ci else 14988c2ecf20Sopenharmony_ci return (struct cvmx_wqe *) cvmx_phys_to_ptr(result.s_work.addr); 14998c2ecf20Sopenharmony_ci} 15008c2ecf20Sopenharmony_ci 15018c2ecf20Sopenharmony_ci/** 15028c2ecf20Sopenharmony_ci * Checks if a work queue entry pointer returned by a work 15038c2ecf20Sopenharmony_ci * request is valid. It may be invalid due to no work 15048c2ecf20Sopenharmony_ci * being available or due to a timeout. 15058c2ecf20Sopenharmony_ci * 15068c2ecf20Sopenharmony_ci * @wqe_ptr: pointer to a work queue entry returned by the POW 15078c2ecf20Sopenharmony_ci * 15088c2ecf20Sopenharmony_ci * Returns 0 if pointer is valid 15098c2ecf20Sopenharmony_ci * 1 if invalid (no work was returned) 15108c2ecf20Sopenharmony_ci */ 15118c2ecf20Sopenharmony_cistatic inline uint64_t cvmx_pow_work_invalid(struct cvmx_wqe *wqe_ptr) 15128c2ecf20Sopenharmony_ci{ 15138c2ecf20Sopenharmony_ci return wqe_ptr == NULL; 15148c2ecf20Sopenharmony_ci} 15158c2ecf20Sopenharmony_ci 15168c2ecf20Sopenharmony_ci/** 15178c2ecf20Sopenharmony_ci * Starts a tag switch to the provided tag value and tag type. 15188c2ecf20Sopenharmony_ci * Completion for the tag switch must be checked for separately. This 15198c2ecf20Sopenharmony_ci * function does NOT update the work queue entry in dram to match tag 15208c2ecf20Sopenharmony_ci * value and type, so the application must keep track of these if they 15218c2ecf20Sopenharmony_ci * are important to the application. This tag switch command must not 15228c2ecf20Sopenharmony_ci * be used for switches to NULL, as the tag switch pending bit will be 15238c2ecf20Sopenharmony_ci * set by the switch request, but never cleared by the hardware. 15248c2ecf20Sopenharmony_ci * 15258c2ecf20Sopenharmony_ci * NOTE: This should not be used when switching from a NULL tag. Use 15268c2ecf20Sopenharmony_ci * cvmx_pow_tag_sw_full() instead. 15278c2ecf20Sopenharmony_ci * 15288c2ecf20Sopenharmony_ci * This function does no checks, so the caller must ensure that any 15298c2ecf20Sopenharmony_ci * previous tag switch has completed. 15308c2ecf20Sopenharmony_ci * 15318c2ecf20Sopenharmony_ci * @tag: new tag value 15328c2ecf20Sopenharmony_ci * @tag_type: new tag type (ordered or atomic) 15338c2ecf20Sopenharmony_ci */ 15348c2ecf20Sopenharmony_cistatic inline void cvmx_pow_tag_sw_nocheck(uint32_t tag, 15358c2ecf20Sopenharmony_ci enum cvmx_pow_tag_type tag_type) 15368c2ecf20Sopenharmony_ci{ 15378c2ecf20Sopenharmony_ci cvmx_addr_t ptr; 15388c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 15398c2ecf20Sopenharmony_ci 15408c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) { 15418c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t current_tag; 15428c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 15438c2ecf20Sopenharmony_ci current_tag = cvmx_pow_get_current_tag(); 15448c2ecf20Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 15458c2ecf20Sopenharmony_ci pr_warn("%s called with NULL_NULL tag\n", __func__); 15468c2ecf20Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 15478c2ecf20Sopenharmony_ci pr_warn("%s called with NULL tag\n", __func__); 15488c2ecf20Sopenharmony_ci if ((current_tag.s.type == tag_type) 15498c2ecf20Sopenharmony_ci && (current_tag.s.tag == tag)) 15508c2ecf20Sopenharmony_ci pr_warn("%s called to perform a tag switch to the same tag\n", 15518c2ecf20Sopenharmony_ci __func__); 15528c2ecf20Sopenharmony_ci if (tag_type == CVMX_POW_TAG_TYPE_NULL) 15538c2ecf20Sopenharmony_ci pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", 15548c2ecf20Sopenharmony_ci __func__); 15558c2ecf20Sopenharmony_ci } 15568c2ecf20Sopenharmony_ci 15578c2ecf20Sopenharmony_ci /* 15588c2ecf20Sopenharmony_ci * Note that WQE in DRAM is not updated here, as the POW does 15598c2ecf20Sopenharmony_ci * not read from DRAM once the WQE is in flight. See hardware 15608c2ecf20Sopenharmony_ci * manual for complete details. It is the application's 15618c2ecf20Sopenharmony_ci * responsibility to keep track of the current tag value if 15628c2ecf20Sopenharmony_ci * that is important. 15638c2ecf20Sopenharmony_ci */ 15648c2ecf20Sopenharmony_ci 15658c2ecf20Sopenharmony_ci tag_req.u64 = 0; 15668c2ecf20Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_SWTAG; 15678c2ecf20Sopenharmony_ci tag_req.s.tag = tag; 15688c2ecf20Sopenharmony_ci tag_req.s.type = tag_type; 15698c2ecf20Sopenharmony_ci 15708c2ecf20Sopenharmony_ci ptr.u64 = 0; 15718c2ecf20Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 15728c2ecf20Sopenharmony_ci ptr.sio.is_io = 1; 15738c2ecf20Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG; 15748c2ecf20Sopenharmony_ci 15758c2ecf20Sopenharmony_ci /* once this store arrives at POW, it will attempt the switch 15768c2ecf20Sopenharmony_ci software must wait for the switch to complete separately */ 15778c2ecf20Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 15788c2ecf20Sopenharmony_ci} 15798c2ecf20Sopenharmony_ci 15808c2ecf20Sopenharmony_ci/** 15818c2ecf20Sopenharmony_ci * Starts a tag switch to the provided tag value and tag type. 15828c2ecf20Sopenharmony_ci * Completion for the tag switch must be checked for separately. This 15838c2ecf20Sopenharmony_ci * function does NOT update the work queue entry in dram to match tag 15848c2ecf20Sopenharmony_ci * value and type, so the application must keep track of these if they 15858c2ecf20Sopenharmony_ci * are important to the application. This tag switch command must not 15868c2ecf20Sopenharmony_ci * be used for switches to NULL, as the tag switch pending bit will be 15878c2ecf20Sopenharmony_ci * set by the switch request, but never cleared by the hardware. 15888c2ecf20Sopenharmony_ci * 15898c2ecf20Sopenharmony_ci * NOTE: This should not be used when switching from a NULL tag. Use 15908c2ecf20Sopenharmony_ci * cvmx_pow_tag_sw_full() instead. 15918c2ecf20Sopenharmony_ci * 15928c2ecf20Sopenharmony_ci * This function waits for any previous tag switch to complete, and also 15938c2ecf20Sopenharmony_ci * displays an error on tag switches to NULL. 15948c2ecf20Sopenharmony_ci * 15958c2ecf20Sopenharmony_ci * @tag: new tag value 15968c2ecf20Sopenharmony_ci * @tag_type: new tag type (ordered or atomic) 15978c2ecf20Sopenharmony_ci */ 15988c2ecf20Sopenharmony_cistatic inline void cvmx_pow_tag_sw(uint32_t tag, 15998c2ecf20Sopenharmony_ci enum cvmx_pow_tag_type tag_type) 16008c2ecf20Sopenharmony_ci{ 16018c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 16028c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 16038c2ecf20Sopenharmony_ci 16048c2ecf20Sopenharmony_ci /* 16058c2ecf20Sopenharmony_ci * Note that WQE in DRAM is not updated here, as the POW does 16068c2ecf20Sopenharmony_ci * not read from DRAM once the WQE is in flight. See hardware 16078c2ecf20Sopenharmony_ci * manual for complete details. It is the application's 16088c2ecf20Sopenharmony_ci * responsibility to keep track of the current tag value if 16098c2ecf20Sopenharmony_ci * that is important. 16108c2ecf20Sopenharmony_ci */ 16118c2ecf20Sopenharmony_ci 16128c2ecf20Sopenharmony_ci /* 16138c2ecf20Sopenharmony_ci * Ensure that there is not a pending tag switch, as a tag 16148c2ecf20Sopenharmony_ci * switch cannot be started if a previous switch is still 16158c2ecf20Sopenharmony_ci * pending. 16168c2ecf20Sopenharmony_ci */ 16178c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_wait(); 16188c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_nocheck(tag, tag_type); 16198c2ecf20Sopenharmony_ci} 16208c2ecf20Sopenharmony_ci 16218c2ecf20Sopenharmony_ci/** 16228c2ecf20Sopenharmony_ci * Starts a tag switch to the provided tag value and tag type. 16238c2ecf20Sopenharmony_ci * Completion for the tag switch must be checked for separately. This 16248c2ecf20Sopenharmony_ci * function does NOT update the work queue entry in dram to match tag 16258c2ecf20Sopenharmony_ci * value and type, so the application must keep track of these if they 16268c2ecf20Sopenharmony_ci * are important to the application. This tag switch command must not 16278c2ecf20Sopenharmony_ci * be used for switches to NULL, as the tag switch pending bit will be 16288c2ecf20Sopenharmony_ci * set by the switch request, but never cleared by the hardware. 16298c2ecf20Sopenharmony_ci * 16308c2ecf20Sopenharmony_ci * This function must be used for tag switches from NULL. 16318c2ecf20Sopenharmony_ci * 16328c2ecf20Sopenharmony_ci * This function does no checks, so the caller must ensure that any 16338c2ecf20Sopenharmony_ci * previous tag switch has completed. 16348c2ecf20Sopenharmony_ci * 16358c2ecf20Sopenharmony_ci * @wqp: pointer to work queue entry to submit. This entry is 16368c2ecf20Sopenharmony_ci * updated to match the other parameters 16378c2ecf20Sopenharmony_ci * @tag: tag value to be assigned to work queue entry 16388c2ecf20Sopenharmony_ci * @tag_type: type of tag 16398c2ecf20Sopenharmony_ci * @group: group value for the work queue entry. 16408c2ecf20Sopenharmony_ci */ 16418c2ecf20Sopenharmony_cistatic inline void cvmx_pow_tag_sw_full_nocheck(struct cvmx_wqe *wqp, uint32_t tag, 16428c2ecf20Sopenharmony_ci enum cvmx_pow_tag_type tag_type, 16438c2ecf20Sopenharmony_ci uint64_t group) 16448c2ecf20Sopenharmony_ci{ 16458c2ecf20Sopenharmony_ci cvmx_addr_t ptr; 16468c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 16478c2ecf20Sopenharmony_ci 16488c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) { 16498c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t current_tag; 16508c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 16518c2ecf20Sopenharmony_ci current_tag = cvmx_pow_get_current_tag(); 16528c2ecf20Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 16538c2ecf20Sopenharmony_ci pr_warn("%s called with NULL_NULL tag\n", __func__); 16548c2ecf20Sopenharmony_ci if ((current_tag.s.type == tag_type) 16558c2ecf20Sopenharmony_ci && (current_tag.s.tag == tag)) 16568c2ecf20Sopenharmony_ci pr_warn("%s called to perform a tag switch to the same tag\n", 16578c2ecf20Sopenharmony_ci __func__); 16588c2ecf20Sopenharmony_ci if (tag_type == CVMX_POW_TAG_TYPE_NULL) 16598c2ecf20Sopenharmony_ci pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", 16608c2ecf20Sopenharmony_ci __func__); 16618c2ecf20Sopenharmony_ci if (wqp != cvmx_phys_to_ptr(0x80)) 16628c2ecf20Sopenharmony_ci if (wqp != cvmx_pow_get_current_wqp()) 16638c2ecf20Sopenharmony_ci pr_warn("%s passed WQE(%p) doesn't match the address in the POW(%p)\n", 16648c2ecf20Sopenharmony_ci __func__, wqp, 16658c2ecf20Sopenharmony_ci cvmx_pow_get_current_wqp()); 16668c2ecf20Sopenharmony_ci } 16678c2ecf20Sopenharmony_ci 16688c2ecf20Sopenharmony_ci /* 16698c2ecf20Sopenharmony_ci * Note that WQE in DRAM is not updated here, as the POW does 16708c2ecf20Sopenharmony_ci * not read from DRAM once the WQE is in flight. See hardware 16718c2ecf20Sopenharmony_ci * manual for complete details. It is the application's 16728c2ecf20Sopenharmony_ci * responsibility to keep track of the current tag value if 16738c2ecf20Sopenharmony_ci * that is important. 16748c2ecf20Sopenharmony_ci */ 16758c2ecf20Sopenharmony_ci 16768c2ecf20Sopenharmony_ci tag_req.u64 = 0; 16778c2ecf20Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_FULL; 16788c2ecf20Sopenharmony_ci tag_req.s.tag = tag; 16798c2ecf20Sopenharmony_ci tag_req.s.type = tag_type; 16808c2ecf20Sopenharmony_ci tag_req.s.grp = group; 16818c2ecf20Sopenharmony_ci 16828c2ecf20Sopenharmony_ci ptr.u64 = 0; 16838c2ecf20Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 16848c2ecf20Sopenharmony_ci ptr.sio.is_io = 1; 16858c2ecf20Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG; 16868c2ecf20Sopenharmony_ci ptr.sio.offset = CAST64(wqp); 16878c2ecf20Sopenharmony_ci 16888c2ecf20Sopenharmony_ci /* 16898c2ecf20Sopenharmony_ci * once this store arrives at POW, it will attempt the switch 16908c2ecf20Sopenharmony_ci * software must wait for the switch to complete separately. 16918c2ecf20Sopenharmony_ci */ 16928c2ecf20Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 16938c2ecf20Sopenharmony_ci} 16948c2ecf20Sopenharmony_ci 16958c2ecf20Sopenharmony_ci/** 16968c2ecf20Sopenharmony_ci * Starts a tag switch to the provided tag value and tag type. 16978c2ecf20Sopenharmony_ci * Completion for the tag switch must be checked for separately. This 16988c2ecf20Sopenharmony_ci * function does NOT update the work queue entry in dram to match tag 16998c2ecf20Sopenharmony_ci * value and type, so the application must keep track of these if they 17008c2ecf20Sopenharmony_ci * are important to the application. This tag switch command must not 17018c2ecf20Sopenharmony_ci * be used for switches to NULL, as the tag switch pending bit will be 17028c2ecf20Sopenharmony_ci * set by the switch request, but never cleared by the hardware. 17038c2ecf20Sopenharmony_ci * 17048c2ecf20Sopenharmony_ci * This function must be used for tag switches from NULL. 17058c2ecf20Sopenharmony_ci * 17068c2ecf20Sopenharmony_ci * This function waits for any pending tag switches to complete 17078c2ecf20Sopenharmony_ci * before requesting the tag switch. 17088c2ecf20Sopenharmony_ci * 17098c2ecf20Sopenharmony_ci * @wqp: pointer to work queue entry to submit. This entry is updated 17108c2ecf20Sopenharmony_ci * to match the other parameters 17118c2ecf20Sopenharmony_ci * @tag: tag value to be assigned to work queue entry 17128c2ecf20Sopenharmony_ci * @tag_type: type of tag 17138c2ecf20Sopenharmony_ci * @group: group value for the work queue entry. 17148c2ecf20Sopenharmony_ci */ 17158c2ecf20Sopenharmony_cistatic inline void cvmx_pow_tag_sw_full(struct cvmx_wqe *wqp, uint32_t tag, 17168c2ecf20Sopenharmony_ci enum cvmx_pow_tag_type tag_type, 17178c2ecf20Sopenharmony_ci uint64_t group) 17188c2ecf20Sopenharmony_ci{ 17198c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 17208c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 17218c2ecf20Sopenharmony_ci 17228c2ecf20Sopenharmony_ci /* 17238c2ecf20Sopenharmony_ci * Ensure that there is not a pending tag switch, as a tag 17248c2ecf20Sopenharmony_ci * switch cannot be started if a previous switch is still 17258c2ecf20Sopenharmony_ci * pending. 17268c2ecf20Sopenharmony_ci */ 17278c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_wait(); 17288c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_full_nocheck(wqp, tag, tag_type, group); 17298c2ecf20Sopenharmony_ci} 17308c2ecf20Sopenharmony_ci 17318c2ecf20Sopenharmony_ci/** 17328c2ecf20Sopenharmony_ci * Switch to a NULL tag, which ends any ordering or 17338c2ecf20Sopenharmony_ci * synchronization provided by the POW for the current 17348c2ecf20Sopenharmony_ci * work queue entry. This operation completes immediately, 17358c2ecf20Sopenharmony_ci * so completion should not be waited for. 17368c2ecf20Sopenharmony_ci * This function does NOT wait for previous tag switches to complete, 17378c2ecf20Sopenharmony_ci * so the caller must ensure that any previous tag switches have completed. 17388c2ecf20Sopenharmony_ci */ 17398c2ecf20Sopenharmony_cistatic inline void cvmx_pow_tag_sw_null_nocheck(void) 17408c2ecf20Sopenharmony_ci{ 17418c2ecf20Sopenharmony_ci cvmx_addr_t ptr; 17428c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 17438c2ecf20Sopenharmony_ci 17448c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) { 17458c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t current_tag; 17468c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 17478c2ecf20Sopenharmony_ci current_tag = cvmx_pow_get_current_tag(); 17488c2ecf20Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 17498c2ecf20Sopenharmony_ci pr_warn("%s called with NULL_NULL tag\n", __func__); 17508c2ecf20Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 17518c2ecf20Sopenharmony_ci pr_warn("%s called when we already have a NULL tag\n", 17528c2ecf20Sopenharmony_ci __func__); 17538c2ecf20Sopenharmony_ci } 17548c2ecf20Sopenharmony_ci 17558c2ecf20Sopenharmony_ci tag_req.u64 = 0; 17568c2ecf20Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_SWTAG; 17578c2ecf20Sopenharmony_ci tag_req.s.type = CVMX_POW_TAG_TYPE_NULL; 17588c2ecf20Sopenharmony_ci 17598c2ecf20Sopenharmony_ci ptr.u64 = 0; 17608c2ecf20Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 17618c2ecf20Sopenharmony_ci ptr.sio.is_io = 1; 17628c2ecf20Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_TAG1; 17638c2ecf20Sopenharmony_ci 17648c2ecf20Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 17658c2ecf20Sopenharmony_ci 17668c2ecf20Sopenharmony_ci /* switch to NULL completes immediately */ 17678c2ecf20Sopenharmony_ci} 17688c2ecf20Sopenharmony_ci 17698c2ecf20Sopenharmony_ci/** 17708c2ecf20Sopenharmony_ci * Switch to a NULL tag, which ends any ordering or 17718c2ecf20Sopenharmony_ci * synchronization provided by the POW for the current 17728c2ecf20Sopenharmony_ci * work queue entry. This operation completes immediately, 17738c2ecf20Sopenharmony_ci * so completion should not be waited for. 17748c2ecf20Sopenharmony_ci * This function waits for any pending tag switches to complete 17758c2ecf20Sopenharmony_ci * before requesting the switch to NULL. 17768c2ecf20Sopenharmony_ci */ 17778c2ecf20Sopenharmony_cistatic inline void cvmx_pow_tag_sw_null(void) 17788c2ecf20Sopenharmony_ci{ 17798c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 17808c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 17818c2ecf20Sopenharmony_ci 17828c2ecf20Sopenharmony_ci /* 17838c2ecf20Sopenharmony_ci * Ensure that there is not a pending tag switch, as a tag 17848c2ecf20Sopenharmony_ci * switch cannot be started if a previous switch is still 17858c2ecf20Sopenharmony_ci * pending. 17868c2ecf20Sopenharmony_ci */ 17878c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_wait(); 17888c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_null_nocheck(); 17898c2ecf20Sopenharmony_ci 17908c2ecf20Sopenharmony_ci /* switch to NULL completes immediately */ 17918c2ecf20Sopenharmony_ci} 17928c2ecf20Sopenharmony_ci 17938c2ecf20Sopenharmony_ci/** 17948c2ecf20Sopenharmony_ci * Submits work to an input queue. This function updates the work 17958c2ecf20Sopenharmony_ci * queue entry in DRAM to match the arguments given. Note that the 17968c2ecf20Sopenharmony_ci * tag provided is for the work queue entry submitted, and is 17978c2ecf20Sopenharmony_ci * unrelated to the tag that the core currently holds. 17988c2ecf20Sopenharmony_ci * 17998c2ecf20Sopenharmony_ci * @wqp: pointer to work queue entry to submit. This entry is 18008c2ecf20Sopenharmony_ci * updated to match the other parameters 18018c2ecf20Sopenharmony_ci * @tag: tag value to be assigned to work queue entry 18028c2ecf20Sopenharmony_ci * @tag_type: type of tag 18038c2ecf20Sopenharmony_ci * @qos: Input queue to add to. 18048c2ecf20Sopenharmony_ci * @grp: group value for the work queue entry. 18058c2ecf20Sopenharmony_ci */ 18068c2ecf20Sopenharmony_cistatic inline void cvmx_pow_work_submit(struct cvmx_wqe *wqp, uint32_t tag, 18078c2ecf20Sopenharmony_ci enum cvmx_pow_tag_type tag_type, 18088c2ecf20Sopenharmony_ci uint64_t qos, uint64_t grp) 18098c2ecf20Sopenharmony_ci{ 18108c2ecf20Sopenharmony_ci cvmx_addr_t ptr; 18118c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 18128c2ecf20Sopenharmony_ci 18138c2ecf20Sopenharmony_ci wqp->word1.tag = tag; 18148c2ecf20Sopenharmony_ci wqp->word1.tag_type = tag_type; 18158c2ecf20Sopenharmony_ci 18168c2ecf20Sopenharmony_ci cvmx_wqe_set_qos(wqp, qos); 18178c2ecf20Sopenharmony_ci cvmx_wqe_set_grp(wqp, grp); 18188c2ecf20Sopenharmony_ci 18198c2ecf20Sopenharmony_ci tag_req.u64 = 0; 18208c2ecf20Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ; 18218c2ecf20Sopenharmony_ci tag_req.s.type = tag_type; 18228c2ecf20Sopenharmony_ci tag_req.s.tag = tag; 18238c2ecf20Sopenharmony_ci tag_req.s.qos = qos; 18248c2ecf20Sopenharmony_ci tag_req.s.grp = grp; 18258c2ecf20Sopenharmony_ci 18268c2ecf20Sopenharmony_ci ptr.u64 = 0; 18278c2ecf20Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 18288c2ecf20Sopenharmony_ci ptr.sio.is_io = 1; 18298c2ecf20Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_TAG1; 18308c2ecf20Sopenharmony_ci ptr.sio.offset = cvmx_ptr_to_phys(wqp); 18318c2ecf20Sopenharmony_ci 18328c2ecf20Sopenharmony_ci /* 18338c2ecf20Sopenharmony_ci * SYNC write to memory before the work submit. This is 18348c2ecf20Sopenharmony_ci * necessary as POW may read values from DRAM at this time. 18358c2ecf20Sopenharmony_ci */ 18368c2ecf20Sopenharmony_ci CVMX_SYNCWS; 18378c2ecf20Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 18388c2ecf20Sopenharmony_ci} 18398c2ecf20Sopenharmony_ci 18408c2ecf20Sopenharmony_ci/** 18418c2ecf20Sopenharmony_ci * This function sets the group mask for a core. The group mask 18428c2ecf20Sopenharmony_ci * indicates which groups each core will accept work from. There are 18438c2ecf20Sopenharmony_ci * 16 groups. 18448c2ecf20Sopenharmony_ci * 18458c2ecf20Sopenharmony_ci * @core_num: core to apply mask to 18468c2ecf20Sopenharmony_ci * @mask: Group mask. There are 16 groups, so only bits 0-15 are valid, 18478c2ecf20Sopenharmony_ci * representing groups 0-15. 18488c2ecf20Sopenharmony_ci * Each 1 bit in the mask enables the core to accept work from 18498c2ecf20Sopenharmony_ci * the corresponding group. 18508c2ecf20Sopenharmony_ci */ 18518c2ecf20Sopenharmony_cistatic inline void cvmx_pow_set_group_mask(uint64_t core_num, uint64_t mask) 18528c2ecf20Sopenharmony_ci{ 18538c2ecf20Sopenharmony_ci union cvmx_pow_pp_grp_mskx grp_msk; 18548c2ecf20Sopenharmony_ci 18558c2ecf20Sopenharmony_ci grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num)); 18568c2ecf20Sopenharmony_ci grp_msk.s.grp_msk = mask; 18578c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64); 18588c2ecf20Sopenharmony_ci} 18598c2ecf20Sopenharmony_ci 18608c2ecf20Sopenharmony_ci/** 18618c2ecf20Sopenharmony_ci * This function sets POW static priorities for a core. Each input queue has 18628c2ecf20Sopenharmony_ci * an associated priority value. 18638c2ecf20Sopenharmony_ci * 18648c2ecf20Sopenharmony_ci * @core_num: core to apply priorities to 18658c2ecf20Sopenharmony_ci * @priority: Vector of 8 priorities, one per POW Input Queue (0-7). 18668c2ecf20Sopenharmony_ci * Highest priority is 0 and lowest is 7. A priority value 18678c2ecf20Sopenharmony_ci * of 0xF instructs POW to skip the Input Queue when 18688c2ecf20Sopenharmony_ci * scheduling to this specific core. 18698c2ecf20Sopenharmony_ci * NOTE: priorities should not have gaps in values, meaning 18708c2ecf20Sopenharmony_ci * {0,1,1,1,1,1,1,1} is a valid configuration while 18718c2ecf20Sopenharmony_ci * {0,2,2,2,2,2,2,2} is not. 18728c2ecf20Sopenharmony_ci */ 18738c2ecf20Sopenharmony_cistatic inline void cvmx_pow_set_priority(uint64_t core_num, 18748c2ecf20Sopenharmony_ci const uint8_t priority[]) 18758c2ecf20Sopenharmony_ci{ 18768c2ecf20Sopenharmony_ci /* POW priorities are supported on CN5xxx and later */ 18778c2ecf20Sopenharmony_ci if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) { 18788c2ecf20Sopenharmony_ci union cvmx_pow_pp_grp_mskx grp_msk; 18798c2ecf20Sopenharmony_ci 18808c2ecf20Sopenharmony_ci grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num)); 18818c2ecf20Sopenharmony_ci grp_msk.s.qos0_pri = priority[0]; 18828c2ecf20Sopenharmony_ci grp_msk.s.qos1_pri = priority[1]; 18838c2ecf20Sopenharmony_ci grp_msk.s.qos2_pri = priority[2]; 18848c2ecf20Sopenharmony_ci grp_msk.s.qos3_pri = priority[3]; 18858c2ecf20Sopenharmony_ci grp_msk.s.qos4_pri = priority[4]; 18868c2ecf20Sopenharmony_ci grp_msk.s.qos5_pri = priority[5]; 18878c2ecf20Sopenharmony_ci grp_msk.s.qos6_pri = priority[6]; 18888c2ecf20Sopenharmony_ci grp_msk.s.qos7_pri = priority[7]; 18898c2ecf20Sopenharmony_ci 18908c2ecf20Sopenharmony_ci /* Detect gaps between priorities and flag error */ 18918c2ecf20Sopenharmony_ci { 18928c2ecf20Sopenharmony_ci int i; 18938c2ecf20Sopenharmony_ci uint32_t prio_mask = 0; 18948c2ecf20Sopenharmony_ci 18958c2ecf20Sopenharmony_ci for (i = 0; i < 8; i++) 18968c2ecf20Sopenharmony_ci if (priority[i] != 0xF) 18978c2ecf20Sopenharmony_ci prio_mask |= 1 << priority[i]; 18988c2ecf20Sopenharmony_ci 18998c2ecf20Sopenharmony_ci if (prio_mask ^ ((1 << cvmx_pop(prio_mask)) - 1)) { 19008c2ecf20Sopenharmony_ci pr_err("POW static priorities should be " 19018c2ecf20Sopenharmony_ci "contiguous (0x%llx)\n", 19028c2ecf20Sopenharmony_ci (unsigned long long)prio_mask); 19038c2ecf20Sopenharmony_ci return; 19048c2ecf20Sopenharmony_ci } 19058c2ecf20Sopenharmony_ci } 19068c2ecf20Sopenharmony_ci 19078c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64); 19088c2ecf20Sopenharmony_ci } 19098c2ecf20Sopenharmony_ci} 19108c2ecf20Sopenharmony_ci 19118c2ecf20Sopenharmony_ci/** 19128c2ecf20Sopenharmony_ci * Performs a tag switch and then an immediate deschedule. This completes 19138c2ecf20Sopenharmony_ci * immediately, so completion must not be waited for. This function does NOT 19148c2ecf20Sopenharmony_ci * update the wqe in DRAM to match arguments. 19158c2ecf20Sopenharmony_ci * 19168c2ecf20Sopenharmony_ci * This function does NOT wait for any prior tag switches to complete, so the 19178c2ecf20Sopenharmony_ci * calling code must do this. 19188c2ecf20Sopenharmony_ci * 19198c2ecf20Sopenharmony_ci * Note the following CAVEAT of the Octeon HW behavior when 19208c2ecf20Sopenharmony_ci * re-scheduling DE-SCHEDULEd items whose (next) state is 19218c2ecf20Sopenharmony_ci * ORDERED: 19228c2ecf20Sopenharmony_ci * - If there are no switches pending at the time that the 19238c2ecf20Sopenharmony_ci * HW executes the de-schedule, the HW will only re-schedule 19248c2ecf20Sopenharmony_ci * the head of the FIFO associated with the given tag. This 19258c2ecf20Sopenharmony_ci * means that in many respects, the HW treats this ORDERED 19268c2ecf20Sopenharmony_ci * tag as an ATOMIC tag. Note that in the SWTAG_DESCH 19278c2ecf20Sopenharmony_ci * case (to an ORDERED tag), the HW will do the switch 19288c2ecf20Sopenharmony_ci * before the deschedule whenever it is possible to do 19298c2ecf20Sopenharmony_ci * the switch immediately, so it may often look like 19308c2ecf20Sopenharmony_ci * this case. 19318c2ecf20Sopenharmony_ci * - If there is a pending switch to ORDERED at the time 19328c2ecf20Sopenharmony_ci * the HW executes the de-schedule, the HW will perform 19338c2ecf20Sopenharmony_ci * the switch at the time it re-schedules, and will be 19348c2ecf20Sopenharmony_ci * able to reschedule any/all of the entries with the 19358c2ecf20Sopenharmony_ci * same tag. 19368c2ecf20Sopenharmony_ci * Due to this behavior, the RECOMMENDATION to software is 19378c2ecf20Sopenharmony_ci * that they have a (next) state of ATOMIC when they 19388c2ecf20Sopenharmony_ci * DE-SCHEDULE. If an ORDERED tag is what was really desired, 19398c2ecf20Sopenharmony_ci * SW can choose to immediately switch to an ORDERED tag 19408c2ecf20Sopenharmony_ci * after the work (that has an ATOMIC tag) is re-scheduled. 19418c2ecf20Sopenharmony_ci * Note that since there are never any tag switches pending 19428c2ecf20Sopenharmony_ci * when the HW re-schedules, this switch can be IMMEDIATE upon 19438c2ecf20Sopenharmony_ci * the reception of the pointer during the re-schedule. 19448c2ecf20Sopenharmony_ci * 19458c2ecf20Sopenharmony_ci * @tag: New tag value 19468c2ecf20Sopenharmony_ci * @tag_type: New tag type 19478c2ecf20Sopenharmony_ci * @group: New group value 19488c2ecf20Sopenharmony_ci * @no_sched: Control whether this work queue entry will be rescheduled. 19498c2ecf20Sopenharmony_ci * - 1 : don't schedule this work 19508c2ecf20Sopenharmony_ci * - 0 : allow this work to be scheduled. 19518c2ecf20Sopenharmony_ci */ 19528c2ecf20Sopenharmony_cistatic inline void cvmx_pow_tag_sw_desched_nocheck( 19538c2ecf20Sopenharmony_ci uint32_t tag, 19548c2ecf20Sopenharmony_ci enum cvmx_pow_tag_type tag_type, 19558c2ecf20Sopenharmony_ci uint64_t group, 19568c2ecf20Sopenharmony_ci uint64_t no_sched) 19578c2ecf20Sopenharmony_ci{ 19588c2ecf20Sopenharmony_ci cvmx_addr_t ptr; 19598c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 19608c2ecf20Sopenharmony_ci 19618c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) { 19628c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t current_tag; 19638c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 19648c2ecf20Sopenharmony_ci current_tag = cvmx_pow_get_current_tag(); 19658c2ecf20Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 19668c2ecf20Sopenharmony_ci pr_warn("%s called with NULL_NULL tag\n", __func__); 19678c2ecf20Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 19688c2ecf20Sopenharmony_ci pr_warn("%s called with NULL tag. Deschedule not allowed from NULL state\n", 19698c2ecf20Sopenharmony_ci __func__); 19708c2ecf20Sopenharmony_ci if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) 19718c2ecf20Sopenharmony_ci && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) 19728c2ecf20Sopenharmony_ci pr_warn("%s called where neither the before or after tag is ATOMIC\n", 19738c2ecf20Sopenharmony_ci __func__); 19748c2ecf20Sopenharmony_ci } 19758c2ecf20Sopenharmony_ci 19768c2ecf20Sopenharmony_ci tag_req.u64 = 0; 19778c2ecf20Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_DESCH; 19788c2ecf20Sopenharmony_ci tag_req.s.tag = tag; 19798c2ecf20Sopenharmony_ci tag_req.s.type = tag_type; 19808c2ecf20Sopenharmony_ci tag_req.s.grp = group; 19818c2ecf20Sopenharmony_ci tag_req.s.no_sched = no_sched; 19828c2ecf20Sopenharmony_ci 19838c2ecf20Sopenharmony_ci ptr.u64 = 0; 19848c2ecf20Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 19858c2ecf20Sopenharmony_ci ptr.sio.is_io = 1; 19868c2ecf20Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_TAG3; 19878c2ecf20Sopenharmony_ci /* 19888c2ecf20Sopenharmony_ci * since TAG3 is used, this store will clear the local pending 19898c2ecf20Sopenharmony_ci * switch bit. 19908c2ecf20Sopenharmony_ci */ 19918c2ecf20Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 19928c2ecf20Sopenharmony_ci} 19938c2ecf20Sopenharmony_ci 19948c2ecf20Sopenharmony_ci/** 19958c2ecf20Sopenharmony_ci * Performs a tag switch and then an immediate deschedule. This completes 19968c2ecf20Sopenharmony_ci * immediately, so completion must not be waited for. This function does NOT 19978c2ecf20Sopenharmony_ci * update the wqe in DRAM to match arguments. 19988c2ecf20Sopenharmony_ci * 19998c2ecf20Sopenharmony_ci * This function waits for any prior tag switches to complete, so the 20008c2ecf20Sopenharmony_ci * calling code may call this function with a pending tag switch. 20018c2ecf20Sopenharmony_ci * 20028c2ecf20Sopenharmony_ci * Note the following CAVEAT of the Octeon HW behavior when 20038c2ecf20Sopenharmony_ci * re-scheduling DE-SCHEDULEd items whose (next) state is 20048c2ecf20Sopenharmony_ci * ORDERED: 20058c2ecf20Sopenharmony_ci * - If there are no switches pending at the time that the 20068c2ecf20Sopenharmony_ci * HW executes the de-schedule, the HW will only re-schedule 20078c2ecf20Sopenharmony_ci * the head of the FIFO associated with the given tag. This 20088c2ecf20Sopenharmony_ci * means that in many respects, the HW treats this ORDERED 20098c2ecf20Sopenharmony_ci * tag as an ATOMIC tag. Note that in the SWTAG_DESCH 20108c2ecf20Sopenharmony_ci * case (to an ORDERED tag), the HW will do the switch 20118c2ecf20Sopenharmony_ci * before the deschedule whenever it is possible to do 20128c2ecf20Sopenharmony_ci * the switch immediately, so it may often look like 20138c2ecf20Sopenharmony_ci * this case. 20148c2ecf20Sopenharmony_ci * - If there is a pending switch to ORDERED at the time 20158c2ecf20Sopenharmony_ci * the HW executes the de-schedule, the HW will perform 20168c2ecf20Sopenharmony_ci * the switch at the time it re-schedules, and will be 20178c2ecf20Sopenharmony_ci * able to reschedule any/all of the entries with the 20188c2ecf20Sopenharmony_ci * same tag. 20198c2ecf20Sopenharmony_ci * Due to this behavior, the RECOMMENDATION to software is 20208c2ecf20Sopenharmony_ci * that they have a (next) state of ATOMIC when they 20218c2ecf20Sopenharmony_ci * DE-SCHEDULE. If an ORDERED tag is what was really desired, 20228c2ecf20Sopenharmony_ci * SW can choose to immediately switch to an ORDERED tag 20238c2ecf20Sopenharmony_ci * after the work (that has an ATOMIC tag) is re-scheduled. 20248c2ecf20Sopenharmony_ci * Note that since there are never any tag switches pending 20258c2ecf20Sopenharmony_ci * when the HW re-schedules, this switch can be IMMEDIATE upon 20268c2ecf20Sopenharmony_ci * the reception of the pointer during the re-schedule. 20278c2ecf20Sopenharmony_ci * 20288c2ecf20Sopenharmony_ci * @tag: New tag value 20298c2ecf20Sopenharmony_ci * @tag_type: New tag type 20308c2ecf20Sopenharmony_ci * @group: New group value 20318c2ecf20Sopenharmony_ci * @no_sched: Control whether this work queue entry will be rescheduled. 20328c2ecf20Sopenharmony_ci * - 1 : don't schedule this work 20338c2ecf20Sopenharmony_ci * - 0 : allow this work to be scheduled. 20348c2ecf20Sopenharmony_ci */ 20358c2ecf20Sopenharmony_cistatic inline void cvmx_pow_tag_sw_desched(uint32_t tag, 20368c2ecf20Sopenharmony_ci enum cvmx_pow_tag_type tag_type, 20378c2ecf20Sopenharmony_ci uint64_t group, uint64_t no_sched) 20388c2ecf20Sopenharmony_ci{ 20398c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 20408c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 20418c2ecf20Sopenharmony_ci 20428c2ecf20Sopenharmony_ci /* Need to make sure any writes to the work queue entry are complete */ 20438c2ecf20Sopenharmony_ci CVMX_SYNCWS; 20448c2ecf20Sopenharmony_ci /* 20458c2ecf20Sopenharmony_ci * Ensure that there is not a pending tag switch, as a tag 20468c2ecf20Sopenharmony_ci * switch cannot be started if a previous switch is still 20478c2ecf20Sopenharmony_ci * pending. 20488c2ecf20Sopenharmony_ci */ 20498c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_wait(); 20508c2ecf20Sopenharmony_ci cvmx_pow_tag_sw_desched_nocheck(tag, tag_type, group, no_sched); 20518c2ecf20Sopenharmony_ci} 20528c2ecf20Sopenharmony_ci 20538c2ecf20Sopenharmony_ci/** 20548c2ecf20Sopenharmony_ci * Deschedules the current work queue entry. 20558c2ecf20Sopenharmony_ci * 20568c2ecf20Sopenharmony_ci * @no_sched: no schedule flag value to be set on the work queue 20578c2ecf20Sopenharmony_ci * entry. If this is set the entry will not be 20588c2ecf20Sopenharmony_ci * rescheduled. 20598c2ecf20Sopenharmony_ci */ 20608c2ecf20Sopenharmony_cistatic inline void cvmx_pow_desched(uint64_t no_sched) 20618c2ecf20Sopenharmony_ci{ 20628c2ecf20Sopenharmony_ci cvmx_addr_t ptr; 20638c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 20648c2ecf20Sopenharmony_ci 20658c2ecf20Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) { 20668c2ecf20Sopenharmony_ci cvmx_pow_tag_req_t current_tag; 20678c2ecf20Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 20688c2ecf20Sopenharmony_ci current_tag = cvmx_pow_get_current_tag(); 20698c2ecf20Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 20708c2ecf20Sopenharmony_ci pr_warn("%s called with NULL_NULL tag\n", __func__); 20718c2ecf20Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 20728c2ecf20Sopenharmony_ci pr_warn("%s called with NULL tag. Deschedule not expected from NULL state\n", 20738c2ecf20Sopenharmony_ci __func__); 20748c2ecf20Sopenharmony_ci } 20758c2ecf20Sopenharmony_ci 20768c2ecf20Sopenharmony_ci /* Need to make sure any writes to the work queue entry are complete */ 20778c2ecf20Sopenharmony_ci CVMX_SYNCWS; 20788c2ecf20Sopenharmony_ci 20798c2ecf20Sopenharmony_ci tag_req.u64 = 0; 20808c2ecf20Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_DESCH; 20818c2ecf20Sopenharmony_ci tag_req.s.no_sched = no_sched; 20828c2ecf20Sopenharmony_ci 20838c2ecf20Sopenharmony_ci ptr.u64 = 0; 20848c2ecf20Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 20858c2ecf20Sopenharmony_ci ptr.sio.is_io = 1; 20868c2ecf20Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_TAG3; 20878c2ecf20Sopenharmony_ci /* 20888c2ecf20Sopenharmony_ci * since TAG3 is used, this store will clear the local pending 20898c2ecf20Sopenharmony_ci * switch bit. 20908c2ecf20Sopenharmony_ci */ 20918c2ecf20Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 20928c2ecf20Sopenharmony_ci} 20938c2ecf20Sopenharmony_ci 20948c2ecf20Sopenharmony_ci/**************************************************** 20958c2ecf20Sopenharmony_ci* Define usage of bits within the 32 bit tag values. 20968c2ecf20Sopenharmony_ci*****************************************************/ 20978c2ecf20Sopenharmony_ci 20988c2ecf20Sopenharmony_ci/* 20998c2ecf20Sopenharmony_ci * Number of bits of the tag used by software. The SW bits are always 21008c2ecf20Sopenharmony_ci * a contiguous block of the high starting at bit 31. The hardware 21018c2ecf20Sopenharmony_ci * bits are always the low bits. By default, the top 8 bits of the 21028c2ecf20Sopenharmony_ci * tag are reserved for software, and the low 24 are set by the IPD 21038c2ecf20Sopenharmony_ci * unit. 21048c2ecf20Sopenharmony_ci */ 21058c2ecf20Sopenharmony_ci#define CVMX_TAG_SW_BITS (8) 21068c2ecf20Sopenharmony_ci#define CVMX_TAG_SW_SHIFT (32 - CVMX_TAG_SW_BITS) 21078c2ecf20Sopenharmony_ci 21088c2ecf20Sopenharmony_ci/* Below is the list of values for the top 8 bits of the tag. */ 21098c2ecf20Sopenharmony_ci/* 21108c2ecf20Sopenharmony_ci * Tag values with top byte of this value are reserved for internal 21118c2ecf20Sopenharmony_ci * executive uses. 21128c2ecf20Sopenharmony_ci */ 21138c2ecf20Sopenharmony_ci#define CVMX_TAG_SW_BITS_INTERNAL 0x1 21148c2ecf20Sopenharmony_ci/* The executive divides the remaining 24 bits as follows: 21158c2ecf20Sopenharmony_ci * - the upper 8 bits (bits 23 - 16 of the tag) define a subgroup 21168c2ecf20Sopenharmony_ci * 21178c2ecf20Sopenharmony_ci * - the lower 16 bits (bits 15 - 0 of the tag) define are the value 21188c2ecf20Sopenharmony_ci * with the subgroup 21198c2ecf20Sopenharmony_ci * 21208c2ecf20Sopenharmony_ci * Note that this section describes the format of tags generated by 21218c2ecf20Sopenharmony_ci * software - refer to the hardware documentation for a description of 21228c2ecf20Sopenharmony_ci * the tags values generated by the packet input hardware. Subgroups 21238c2ecf20Sopenharmony_ci * are defined here. 21248c2ecf20Sopenharmony_ci */ 21258c2ecf20Sopenharmony_ci/* Mask for the value portion of the tag */ 21268c2ecf20Sopenharmony_ci#define CVMX_TAG_SUBGROUP_MASK 0xFFFF 21278c2ecf20Sopenharmony_ci#define CVMX_TAG_SUBGROUP_SHIFT 16 21288c2ecf20Sopenharmony_ci#define CVMX_TAG_SUBGROUP_PKO 0x1 21298c2ecf20Sopenharmony_ci 21308c2ecf20Sopenharmony_ci/* End of executive tag subgroup definitions */ 21318c2ecf20Sopenharmony_ci 21328c2ecf20Sopenharmony_ci/* 21338c2ecf20Sopenharmony_ci * The remaining values software bit values 0x2 - 0xff are available 21348c2ecf20Sopenharmony_ci * for application use. 21358c2ecf20Sopenharmony_ci */ 21368c2ecf20Sopenharmony_ci 21378c2ecf20Sopenharmony_ci/** 21388c2ecf20Sopenharmony_ci * This function creates a 32 bit tag value from the two values provided. 21398c2ecf20Sopenharmony_ci * 21408c2ecf20Sopenharmony_ci * @sw_bits: The upper bits (number depends on configuration) are set 21418c2ecf20Sopenharmony_ci * to this value. The remainder of bits are set by the 21428c2ecf20Sopenharmony_ci * hw_bits parameter. 21438c2ecf20Sopenharmony_ci * 21448c2ecf20Sopenharmony_ci * @hw_bits: The lower bits (number depends on configuration) are set 21458c2ecf20Sopenharmony_ci * to this value. The remainder of bits are set by the 21468c2ecf20Sopenharmony_ci * sw_bits parameter. 21478c2ecf20Sopenharmony_ci * 21488c2ecf20Sopenharmony_ci * Returns 32 bit value of the combined hw and sw bits. 21498c2ecf20Sopenharmony_ci */ 21508c2ecf20Sopenharmony_cistatic inline uint32_t cvmx_pow_tag_compose(uint64_t sw_bits, uint64_t hw_bits) 21518c2ecf20Sopenharmony_ci{ 21528c2ecf20Sopenharmony_ci return ((sw_bits & cvmx_build_mask(CVMX_TAG_SW_BITS)) << 21538c2ecf20Sopenharmony_ci CVMX_TAG_SW_SHIFT) | 21548c2ecf20Sopenharmony_ci (hw_bits & cvmx_build_mask(32 - CVMX_TAG_SW_BITS)); 21558c2ecf20Sopenharmony_ci} 21568c2ecf20Sopenharmony_ci 21578c2ecf20Sopenharmony_ci/** 21588c2ecf20Sopenharmony_ci * Extracts the bits allocated for software use from the tag 21598c2ecf20Sopenharmony_ci * 21608c2ecf20Sopenharmony_ci * @tag: 32 bit tag value 21618c2ecf20Sopenharmony_ci * 21628c2ecf20Sopenharmony_ci * Returns N bit software tag value, where N is configurable with the 21638c2ecf20Sopenharmony_ci * CVMX_TAG_SW_BITS define 21648c2ecf20Sopenharmony_ci */ 21658c2ecf20Sopenharmony_cistatic inline uint32_t cvmx_pow_tag_get_sw_bits(uint64_t tag) 21668c2ecf20Sopenharmony_ci{ 21678c2ecf20Sopenharmony_ci return (tag >> (32 - CVMX_TAG_SW_BITS)) & 21688c2ecf20Sopenharmony_ci cvmx_build_mask(CVMX_TAG_SW_BITS); 21698c2ecf20Sopenharmony_ci} 21708c2ecf20Sopenharmony_ci 21718c2ecf20Sopenharmony_ci/** 21728c2ecf20Sopenharmony_ci * 21738c2ecf20Sopenharmony_ci * Extracts the bits allocated for hardware use from the tag 21748c2ecf20Sopenharmony_ci * 21758c2ecf20Sopenharmony_ci * @tag: 32 bit tag value 21768c2ecf20Sopenharmony_ci * 21778c2ecf20Sopenharmony_ci * Returns (32 - N) bit software tag value, where N is configurable 21788c2ecf20Sopenharmony_ci * with the CVMX_TAG_SW_BITS define 21798c2ecf20Sopenharmony_ci */ 21808c2ecf20Sopenharmony_cistatic inline uint32_t cvmx_pow_tag_get_hw_bits(uint64_t tag) 21818c2ecf20Sopenharmony_ci{ 21828c2ecf20Sopenharmony_ci return tag & cvmx_build_mask(32 - CVMX_TAG_SW_BITS); 21838c2ecf20Sopenharmony_ci} 21848c2ecf20Sopenharmony_ci 21858c2ecf20Sopenharmony_ci/** 21868c2ecf20Sopenharmony_ci * Store the current POW internal state into the supplied 21878c2ecf20Sopenharmony_ci * buffer. It is recommended that you pass a buffer of at least 21888c2ecf20Sopenharmony_ci * 128KB. The format of the capture may change based on SDK 21898c2ecf20Sopenharmony_ci * version and Octeon chip. 21908c2ecf20Sopenharmony_ci * 21918c2ecf20Sopenharmony_ci * @buffer: Buffer to store capture into 21928c2ecf20Sopenharmony_ci * @buffer_size: 21938c2ecf20Sopenharmony_ci * The size of the supplied buffer 21948c2ecf20Sopenharmony_ci * 21958c2ecf20Sopenharmony_ci * Returns Zero on success, negative on failure 21968c2ecf20Sopenharmony_ci */ 21978c2ecf20Sopenharmony_ciextern int cvmx_pow_capture(void *buffer, int buffer_size); 21988c2ecf20Sopenharmony_ci 21998c2ecf20Sopenharmony_ci/** 22008c2ecf20Sopenharmony_ci * Dump a POW capture to the console in a human readable format. 22018c2ecf20Sopenharmony_ci * 22028c2ecf20Sopenharmony_ci * @buffer: POW capture from cvmx_pow_capture() 22038c2ecf20Sopenharmony_ci * @buffer_size: 22048c2ecf20Sopenharmony_ci * Size of the buffer 22058c2ecf20Sopenharmony_ci */ 22068c2ecf20Sopenharmony_ciextern void cvmx_pow_display(void *buffer, int buffer_size); 22078c2ecf20Sopenharmony_ci 22088c2ecf20Sopenharmony_ci/** 22098c2ecf20Sopenharmony_ci * Return the number of POW entries supported by this chip 22108c2ecf20Sopenharmony_ci * 22118c2ecf20Sopenharmony_ci * Returns Number of POW entries 22128c2ecf20Sopenharmony_ci */ 22138c2ecf20Sopenharmony_ciextern int cvmx_pow_get_num_entries(void); 22148c2ecf20Sopenharmony_ci 22158c2ecf20Sopenharmony_ci#endif /* __CVMX_POW_H__ */ 2216