162306a36Sopenharmony_ci/***********************license start*************** 262306a36Sopenharmony_ci * Author: Cavium Networks 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Contact: support@caviumnetworks.com 562306a36Sopenharmony_ci * This file is part of the OCTEON SDK 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (c) 2003-2008 Cavium Networks 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * This file is free software; you can redistribute it and/or modify 1062306a36Sopenharmony_ci * it under the terms of the GNU General Public License, Version 2, as 1162306a36Sopenharmony_ci * published by the Free Software Foundation. 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * This file is distributed in the hope that it will be useful, but 1462306a36Sopenharmony_ci * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 1562306a36Sopenharmony_ci * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 1662306a36Sopenharmony_ci * NONINFRINGEMENT. See the GNU General Public License for more 1762306a36Sopenharmony_ci * details. 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * You should have received a copy of the GNU General Public License 2062306a36Sopenharmony_ci * along with this file; if not, write to the Free Software 2162306a36Sopenharmony_ci * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2262306a36Sopenharmony_ci * or visit http://www.gnu.org/licenses/. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * This file may also be available under a different license from Cavium. 2562306a36Sopenharmony_ci * Contact Cavium Networks for more information 2662306a36Sopenharmony_ci ***********************license end**************************************/ 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/** 2962306a36Sopenharmony_ci * Interface to the hardware Packet Order / Work unit. 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * New, starting with SDK 1.7.0, cvmx-pow supports a number of 3262306a36Sopenharmony_ci * extended consistency checks. The define 3362306a36Sopenharmony_ci * CVMX_ENABLE_POW_CHECKS controls the runtime insertion of POW 3462306a36Sopenharmony_ci * internal state checks to find common programming errors. If 3562306a36Sopenharmony_ci * CVMX_ENABLE_POW_CHECKS is not defined, checks are by default 3662306a36Sopenharmony_ci * enabled. For example, cvmx-pow will check for the following 3762306a36Sopenharmony_ci * program errors or POW state inconsistency. 3862306a36Sopenharmony_ci * - Requesting a POW operation with an active tag switch in 3962306a36Sopenharmony_ci * progress. 4062306a36Sopenharmony_ci * - Waiting for a tag switch to complete for an excessively 4162306a36Sopenharmony_ci * long period. This is normally a sign of an error in locking 4262306a36Sopenharmony_ci * causing deadlock. 4362306a36Sopenharmony_ci * - Illegal tag switches from NULL_NULL. 4462306a36Sopenharmony_ci * - Illegal tag switches from NULL. 4562306a36Sopenharmony_ci * - Illegal deschedule request. 4662306a36Sopenharmony_ci * - WQE pointer not matching the one attached to the core by 4762306a36Sopenharmony_ci * the POW. 4862306a36Sopenharmony_ci * 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#ifndef __CVMX_POW_H__ 5262306a36Sopenharmony_ci#define __CVMX_POW_H__ 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#include <asm/octeon/cvmx-pow-defs.h> 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#include <asm/octeon/cvmx-scratch.h> 5762306a36Sopenharmony_ci#include <asm/octeon/cvmx-wqe.h> 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/* Default to having all POW constancy checks turned on */ 6062306a36Sopenharmony_ci#ifndef CVMX_ENABLE_POW_CHECKS 6162306a36Sopenharmony_ci#define CVMX_ENABLE_POW_CHECKS 1 6262306a36Sopenharmony_ci#endif 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cienum cvmx_pow_tag_type { 6562306a36Sopenharmony_ci /* Tag ordering is maintained */ 6662306a36Sopenharmony_ci CVMX_POW_TAG_TYPE_ORDERED = 0L, 6762306a36Sopenharmony_ci /* Tag ordering is maintained, and at most one PP has the tag */ 6862306a36Sopenharmony_ci CVMX_POW_TAG_TYPE_ATOMIC = 1L, 6962306a36Sopenharmony_ci /* 7062306a36Sopenharmony_ci * The work queue entry from the order - NEVER tag switch from 7162306a36Sopenharmony_ci * NULL to NULL 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ci CVMX_POW_TAG_TYPE_NULL = 2L, 7462306a36Sopenharmony_ci /* A tag switch to NULL, and there is no space reserved in POW 7562306a36Sopenharmony_ci * - NEVER tag switch to NULL_NULL 7662306a36Sopenharmony_ci * - NEVER tag switch from NULL_NULL 7762306a36Sopenharmony_ci * - NULL_NULL is entered at the beginning of time and on a deschedule. 7862306a36Sopenharmony_ci * - NULL_NULL can be exited by a new work request. A NULL_SWITCH 7962306a36Sopenharmony_ci * load can also switch the state to NULL 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_ci CVMX_POW_TAG_TYPE_NULL_NULL = 3L 8262306a36Sopenharmony_ci}; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci/** 8562306a36Sopenharmony_ci * Wait flag values for pow functions. 8662306a36Sopenharmony_ci */ 8762306a36Sopenharmony_citypedef enum { 8862306a36Sopenharmony_ci CVMX_POW_WAIT = 1, 8962306a36Sopenharmony_ci CVMX_POW_NO_WAIT = 0, 9062306a36Sopenharmony_ci} cvmx_pow_wait_t; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/** 9362306a36Sopenharmony_ci * POW tag operations. These are used in the data stored to the POW. 9462306a36Sopenharmony_ci */ 9562306a36Sopenharmony_citypedef enum { 9662306a36Sopenharmony_ci /* 9762306a36Sopenharmony_ci * switch the tag (only) for this PP 9862306a36Sopenharmony_ci * - the previous tag should be non-NULL in this case 9962306a36Sopenharmony_ci * - tag switch response required 10062306a36Sopenharmony_ci * - fields used: op, type, tag 10162306a36Sopenharmony_ci */ 10262306a36Sopenharmony_ci CVMX_POW_TAG_OP_SWTAG = 0L, 10362306a36Sopenharmony_ci /* 10462306a36Sopenharmony_ci * switch the tag for this PP, with full information 10562306a36Sopenharmony_ci * - this should be used when the previous tag is NULL 10662306a36Sopenharmony_ci * - tag switch response required 10762306a36Sopenharmony_ci * - fields used: address, op, grp, type, tag 10862306a36Sopenharmony_ci */ 10962306a36Sopenharmony_ci CVMX_POW_TAG_OP_SWTAG_FULL = 1L, 11062306a36Sopenharmony_ci /* 11162306a36Sopenharmony_ci * switch the tag (and/or group) for this PP and de-schedule 11262306a36Sopenharmony_ci * - OK to keep the tag the same and only change the group 11362306a36Sopenharmony_ci * - fields used: op, no_sched, grp, type, tag 11462306a36Sopenharmony_ci */ 11562306a36Sopenharmony_ci CVMX_POW_TAG_OP_SWTAG_DESCH = 2L, 11662306a36Sopenharmony_ci /* 11762306a36Sopenharmony_ci * just de-schedule 11862306a36Sopenharmony_ci * - fields used: op, no_sched 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_ci CVMX_POW_TAG_OP_DESCH = 3L, 12162306a36Sopenharmony_ci /* 12262306a36Sopenharmony_ci * create an entirely new work queue entry 12362306a36Sopenharmony_ci * - fields used: address, op, qos, grp, type, tag 12462306a36Sopenharmony_ci */ 12562306a36Sopenharmony_ci CVMX_POW_TAG_OP_ADDWQ = 4L, 12662306a36Sopenharmony_ci /* 12762306a36Sopenharmony_ci * just update the work queue pointer and grp for this PP 12862306a36Sopenharmony_ci * - fields used: address, op, grp 12962306a36Sopenharmony_ci */ 13062306a36Sopenharmony_ci CVMX_POW_TAG_OP_UPDATE_WQP_GRP = 5L, 13162306a36Sopenharmony_ci /* 13262306a36Sopenharmony_ci * set the no_sched bit on the de-schedule list 13362306a36Sopenharmony_ci * 13462306a36Sopenharmony_ci * - does nothing if the selected entry is not on the 13562306a36Sopenharmony_ci * de-schedule list 13662306a36Sopenharmony_ci * 13762306a36Sopenharmony_ci * - does nothing if the stored work queue pointer does not 13862306a36Sopenharmony_ci * match the address field 13962306a36Sopenharmony_ci * 14062306a36Sopenharmony_ci * - fields used: address, index, op 14162306a36Sopenharmony_ci * 14262306a36Sopenharmony_ci * Before issuing a *_NSCHED operation, SW must guarantee 14362306a36Sopenharmony_ci * that all prior deschedules and set/clr NSCHED operations 14462306a36Sopenharmony_ci * are complete and all prior switches are complete. The 14562306a36Sopenharmony_ci * hardware provides the opsdone bit and swdone bit for SW 14662306a36Sopenharmony_ci * polling. After issuing a *_NSCHED operation, SW must 14762306a36Sopenharmony_ci * guarantee that the set/clr NSCHED is complete before any 14862306a36Sopenharmony_ci * subsequent operations. 14962306a36Sopenharmony_ci */ 15062306a36Sopenharmony_ci CVMX_POW_TAG_OP_SET_NSCHED = 6L, 15162306a36Sopenharmony_ci /* 15262306a36Sopenharmony_ci * clears the no_sched bit on the de-schedule list 15362306a36Sopenharmony_ci * 15462306a36Sopenharmony_ci * - does nothing if the selected entry is not on the 15562306a36Sopenharmony_ci * de-schedule list 15662306a36Sopenharmony_ci * 15762306a36Sopenharmony_ci * - does nothing if the stored work queue pointer does not 15862306a36Sopenharmony_ci * match the address field 15962306a36Sopenharmony_ci * 16062306a36Sopenharmony_ci * - fields used: address, index, op 16162306a36Sopenharmony_ci * 16262306a36Sopenharmony_ci * Before issuing a *_NSCHED operation, SW must guarantee that 16362306a36Sopenharmony_ci * all prior deschedules and set/clr NSCHED operations are 16462306a36Sopenharmony_ci * complete and all prior switches are complete. The hardware 16562306a36Sopenharmony_ci * provides the opsdone bit and swdone bit for SW 16662306a36Sopenharmony_ci * polling. After issuing a *_NSCHED operation, SW must 16762306a36Sopenharmony_ci * guarantee that the set/clr NSCHED is complete before any 16862306a36Sopenharmony_ci * subsequent operations. 16962306a36Sopenharmony_ci */ 17062306a36Sopenharmony_ci CVMX_POW_TAG_OP_CLR_NSCHED = 7L, 17162306a36Sopenharmony_ci /* do nothing */ 17262306a36Sopenharmony_ci CVMX_POW_TAG_OP_NOP = 15L 17362306a36Sopenharmony_ci} cvmx_pow_tag_op_t; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci/** 17662306a36Sopenharmony_ci * This structure defines the store data on a store to POW 17762306a36Sopenharmony_ci */ 17862306a36Sopenharmony_citypedef union { 17962306a36Sopenharmony_ci uint64_t u64; 18062306a36Sopenharmony_ci struct { 18162306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 18262306a36Sopenharmony_ci /* 18362306a36Sopenharmony_ci * Don't reschedule this entry. no_sched is used for 18462306a36Sopenharmony_ci * CVMX_POW_TAG_OP_SWTAG_DESCH and 18562306a36Sopenharmony_ci * CVMX_POW_TAG_OP_DESCH 18662306a36Sopenharmony_ci */ 18762306a36Sopenharmony_ci uint64_t no_sched:1; 18862306a36Sopenharmony_ci uint64_t unused:2; 18962306a36Sopenharmony_ci /* Tontains index of entry for a CVMX_POW_TAG_OP_*_NSCHED */ 19062306a36Sopenharmony_ci uint64_t index:13; 19162306a36Sopenharmony_ci /* The operation to perform */ 19262306a36Sopenharmony_ci cvmx_pow_tag_op_t op:4; 19362306a36Sopenharmony_ci uint64_t unused2:2; 19462306a36Sopenharmony_ci /* 19562306a36Sopenharmony_ci * The QOS level for the packet. qos is only used for 19662306a36Sopenharmony_ci * CVMX_POW_TAG_OP_ADDWQ 19762306a36Sopenharmony_ci */ 19862306a36Sopenharmony_ci uint64_t qos:3; 19962306a36Sopenharmony_ci /* 20062306a36Sopenharmony_ci * The group that the work queue entry will be 20162306a36Sopenharmony_ci * scheduled to grp is used for CVMX_POW_TAG_OP_ADDWQ, 20262306a36Sopenharmony_ci * CVMX_POW_TAG_OP_SWTAG_FULL, 20362306a36Sopenharmony_ci * CVMX_POW_TAG_OP_SWTAG_DESCH, and 20462306a36Sopenharmony_ci * CVMX_POW_TAG_OP_UPDATE_WQP_GRP 20562306a36Sopenharmony_ci */ 20662306a36Sopenharmony_ci uint64_t grp:4; 20762306a36Sopenharmony_ci /* 20862306a36Sopenharmony_ci * The type of the tag. type is used for everything 20962306a36Sopenharmony_ci * except CVMX_POW_TAG_OP_DESCH, 21062306a36Sopenharmony_ci * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and 21162306a36Sopenharmony_ci * CVMX_POW_TAG_OP_*_NSCHED 21262306a36Sopenharmony_ci */ 21362306a36Sopenharmony_ci uint64_t type:3; 21462306a36Sopenharmony_ci /* 21562306a36Sopenharmony_ci * The actual tag. tag is used for everything except 21662306a36Sopenharmony_ci * CVMX_POW_TAG_OP_DESCH, 21762306a36Sopenharmony_ci * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and 21862306a36Sopenharmony_ci * CVMX_POW_TAG_OP_*_NSCHED 21962306a36Sopenharmony_ci */ 22062306a36Sopenharmony_ci uint64_t tag:32; 22162306a36Sopenharmony_ci#else 22262306a36Sopenharmony_ci uint64_t tag:32; 22362306a36Sopenharmony_ci uint64_t type:3; 22462306a36Sopenharmony_ci uint64_t grp:4; 22562306a36Sopenharmony_ci uint64_t qos:3; 22662306a36Sopenharmony_ci uint64_t unused2:2; 22762306a36Sopenharmony_ci cvmx_pow_tag_op_t op:4; 22862306a36Sopenharmony_ci uint64_t index:13; 22962306a36Sopenharmony_ci uint64_t unused:2; 23062306a36Sopenharmony_ci uint64_t no_sched:1; 23162306a36Sopenharmony_ci#endif 23262306a36Sopenharmony_ci } s; 23362306a36Sopenharmony_ci} cvmx_pow_tag_req_t; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci/** 23662306a36Sopenharmony_ci * This structure describes the address to load stuff from POW 23762306a36Sopenharmony_ci */ 23862306a36Sopenharmony_citypedef union { 23962306a36Sopenharmony_ci uint64_t u64; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci /** 24262306a36Sopenharmony_ci * Address for new work request loads (did<2:0> == 0) 24362306a36Sopenharmony_ci */ 24462306a36Sopenharmony_ci struct { 24562306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 24662306a36Sopenharmony_ci /* Mips64 address region. Should be CVMX_IO_SEG */ 24762306a36Sopenharmony_ci uint64_t mem_region:2; 24862306a36Sopenharmony_ci /* Must be zero */ 24962306a36Sopenharmony_ci uint64_t reserved_49_61:13; 25062306a36Sopenharmony_ci /* Must be one */ 25162306a36Sopenharmony_ci uint64_t is_io:1; 25262306a36Sopenharmony_ci /* the ID of POW -- did<2:0> == 0 in this case */ 25362306a36Sopenharmony_ci uint64_t did:8; 25462306a36Sopenharmony_ci /* Must be zero */ 25562306a36Sopenharmony_ci uint64_t reserved_4_39:36; 25662306a36Sopenharmony_ci /* 25762306a36Sopenharmony_ci * If set, don't return load response until work is 25862306a36Sopenharmony_ci * available. 25962306a36Sopenharmony_ci */ 26062306a36Sopenharmony_ci uint64_t wait:1; 26162306a36Sopenharmony_ci /* Must be zero */ 26262306a36Sopenharmony_ci uint64_t reserved_0_2:3; 26362306a36Sopenharmony_ci#else 26462306a36Sopenharmony_ci uint64_t reserved_0_2:3; 26562306a36Sopenharmony_ci uint64_t wait:1; 26662306a36Sopenharmony_ci uint64_t reserved_4_39:36; 26762306a36Sopenharmony_ci uint64_t did:8; 26862306a36Sopenharmony_ci uint64_t is_io:1; 26962306a36Sopenharmony_ci uint64_t reserved_49_61:13; 27062306a36Sopenharmony_ci uint64_t mem_region:2; 27162306a36Sopenharmony_ci#endif 27262306a36Sopenharmony_ci } swork; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci /** 27562306a36Sopenharmony_ci * Address for loads to get POW internal status 27662306a36Sopenharmony_ci */ 27762306a36Sopenharmony_ci struct { 27862306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 27962306a36Sopenharmony_ci /* Mips64 address region. Should be CVMX_IO_SEG */ 28062306a36Sopenharmony_ci uint64_t mem_region:2; 28162306a36Sopenharmony_ci /* Must be zero */ 28262306a36Sopenharmony_ci uint64_t reserved_49_61:13; 28362306a36Sopenharmony_ci /* Must be one */ 28462306a36Sopenharmony_ci uint64_t is_io:1; 28562306a36Sopenharmony_ci /* the ID of POW -- did<2:0> == 1 in this case */ 28662306a36Sopenharmony_ci uint64_t did:8; 28762306a36Sopenharmony_ci /* Must be zero */ 28862306a36Sopenharmony_ci uint64_t reserved_10_39:30; 28962306a36Sopenharmony_ci /* The core id to get status for */ 29062306a36Sopenharmony_ci uint64_t coreid:4; 29162306a36Sopenharmony_ci /* 29262306a36Sopenharmony_ci * If set and get_cur is set, return reverse tag-list 29362306a36Sopenharmony_ci * pointer rather than forward tag-list pointer. 29462306a36Sopenharmony_ci */ 29562306a36Sopenharmony_ci uint64_t get_rev:1; 29662306a36Sopenharmony_ci /* 29762306a36Sopenharmony_ci * If set, return current status rather than pending 29862306a36Sopenharmony_ci * status. 29962306a36Sopenharmony_ci */ 30062306a36Sopenharmony_ci uint64_t get_cur:1; 30162306a36Sopenharmony_ci /* 30262306a36Sopenharmony_ci * If set, get the work-queue pointer rather than 30362306a36Sopenharmony_ci * tag/type. 30462306a36Sopenharmony_ci */ 30562306a36Sopenharmony_ci uint64_t get_wqp:1; 30662306a36Sopenharmony_ci /* Must be zero */ 30762306a36Sopenharmony_ci uint64_t reserved_0_2:3; 30862306a36Sopenharmony_ci#else 30962306a36Sopenharmony_ci uint64_t reserved_0_2:3; 31062306a36Sopenharmony_ci uint64_t get_wqp:1; 31162306a36Sopenharmony_ci uint64_t get_cur:1; 31262306a36Sopenharmony_ci uint64_t get_rev:1; 31362306a36Sopenharmony_ci uint64_t coreid:4; 31462306a36Sopenharmony_ci uint64_t reserved_10_39:30; 31562306a36Sopenharmony_ci uint64_t did:8; 31662306a36Sopenharmony_ci uint64_t is_io:1; 31762306a36Sopenharmony_ci uint64_t reserved_49_61:13; 31862306a36Sopenharmony_ci uint64_t mem_region:2; 31962306a36Sopenharmony_ci#endif 32062306a36Sopenharmony_ci } sstatus; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci /** 32362306a36Sopenharmony_ci * Address for memory loads to get POW internal state 32462306a36Sopenharmony_ci */ 32562306a36Sopenharmony_ci struct { 32662306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 32762306a36Sopenharmony_ci /* Mips64 address region. Should be CVMX_IO_SEG */ 32862306a36Sopenharmony_ci uint64_t mem_region:2; 32962306a36Sopenharmony_ci /* Must be zero */ 33062306a36Sopenharmony_ci uint64_t reserved_49_61:13; 33162306a36Sopenharmony_ci /* Must be one */ 33262306a36Sopenharmony_ci uint64_t is_io:1; 33362306a36Sopenharmony_ci /* the ID of POW -- did<2:0> == 2 in this case */ 33462306a36Sopenharmony_ci uint64_t did:8; 33562306a36Sopenharmony_ci /* Must be zero */ 33662306a36Sopenharmony_ci uint64_t reserved_16_39:24; 33762306a36Sopenharmony_ci /* POW memory index */ 33862306a36Sopenharmony_ci uint64_t index:11; 33962306a36Sopenharmony_ci /* 34062306a36Sopenharmony_ci * If set, return deschedule information rather than 34162306a36Sopenharmony_ci * the standard response for work-queue index (invalid 34262306a36Sopenharmony_ci * if the work-queue entry is not on the deschedule 34362306a36Sopenharmony_ci * list). 34462306a36Sopenharmony_ci */ 34562306a36Sopenharmony_ci uint64_t get_des:1; 34662306a36Sopenharmony_ci /* 34762306a36Sopenharmony_ci * If set, get the work-queue pointer rather than 34862306a36Sopenharmony_ci * tag/type (no effect when get_des set). 34962306a36Sopenharmony_ci */ 35062306a36Sopenharmony_ci uint64_t get_wqp:1; 35162306a36Sopenharmony_ci /* Must be zero */ 35262306a36Sopenharmony_ci uint64_t reserved_0_2:3; 35362306a36Sopenharmony_ci#else 35462306a36Sopenharmony_ci uint64_t reserved_0_2:3; 35562306a36Sopenharmony_ci uint64_t get_wqp:1; 35662306a36Sopenharmony_ci uint64_t get_des:1; 35762306a36Sopenharmony_ci uint64_t index:11; 35862306a36Sopenharmony_ci uint64_t reserved_16_39:24; 35962306a36Sopenharmony_ci uint64_t did:8; 36062306a36Sopenharmony_ci uint64_t is_io:1; 36162306a36Sopenharmony_ci uint64_t reserved_49_61:13; 36262306a36Sopenharmony_ci uint64_t mem_region:2; 36362306a36Sopenharmony_ci#endif 36462306a36Sopenharmony_ci } smemload; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci /** 36762306a36Sopenharmony_ci * Address for index/pointer loads 36862306a36Sopenharmony_ci */ 36962306a36Sopenharmony_ci struct { 37062306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 37162306a36Sopenharmony_ci /* Mips64 address region. Should be CVMX_IO_SEG */ 37262306a36Sopenharmony_ci uint64_t mem_region:2; 37362306a36Sopenharmony_ci /* Must be zero */ 37462306a36Sopenharmony_ci uint64_t reserved_49_61:13; 37562306a36Sopenharmony_ci /* Must be one */ 37662306a36Sopenharmony_ci uint64_t is_io:1; 37762306a36Sopenharmony_ci /* the ID of POW -- did<2:0> == 3 in this case */ 37862306a36Sopenharmony_ci uint64_t did:8; 37962306a36Sopenharmony_ci /* Must be zero */ 38062306a36Sopenharmony_ci uint64_t reserved_9_39:31; 38162306a36Sopenharmony_ci /* 38262306a36Sopenharmony_ci * when {get_rmt ==0 AND get_des_get_tail == 0}, this 38362306a36Sopenharmony_ci * field selects one of eight POW internal-input 38462306a36Sopenharmony_ci * queues (0-7), one per QOS level; values 8-15 are 38562306a36Sopenharmony_ci * illegal in this case; when {get_rmt ==0 AND 38662306a36Sopenharmony_ci * get_des_get_tail == 1}, this field selects one of 38762306a36Sopenharmony_ci * 16 deschedule lists (per group); when get_rmt ==1, 38862306a36Sopenharmony_ci * this field selects one of 16 memory-input queue 38962306a36Sopenharmony_ci * lists. The two memory-input queue lists associated 39062306a36Sopenharmony_ci * with each QOS level are: 39162306a36Sopenharmony_ci * 39262306a36Sopenharmony_ci * - qosgrp = 0, qosgrp = 8: QOS0 39362306a36Sopenharmony_ci * - qosgrp = 1, qosgrp = 9: QOS1 39462306a36Sopenharmony_ci * - qosgrp = 2, qosgrp = 10: QOS2 39562306a36Sopenharmony_ci * - qosgrp = 3, qosgrp = 11: QOS3 39662306a36Sopenharmony_ci * - qosgrp = 4, qosgrp = 12: QOS4 39762306a36Sopenharmony_ci * - qosgrp = 5, qosgrp = 13: QOS5 39862306a36Sopenharmony_ci * - qosgrp = 6, qosgrp = 14: QOS6 39962306a36Sopenharmony_ci * - qosgrp = 7, qosgrp = 15: QOS7 40062306a36Sopenharmony_ci */ 40162306a36Sopenharmony_ci uint64_t qosgrp:4; 40262306a36Sopenharmony_ci /* 40362306a36Sopenharmony_ci * If set and get_rmt is clear, return deschedule list 40462306a36Sopenharmony_ci * indexes rather than indexes for the specified qos 40562306a36Sopenharmony_ci * level; if set and get_rmt is set, return the tail 40662306a36Sopenharmony_ci * pointer rather than the head pointer for the 40762306a36Sopenharmony_ci * specified qos level. 40862306a36Sopenharmony_ci */ 40962306a36Sopenharmony_ci uint64_t get_des_get_tail:1; 41062306a36Sopenharmony_ci /* 41162306a36Sopenharmony_ci * If set, return remote pointers rather than the 41262306a36Sopenharmony_ci * local indexes for the specified qos level. 41362306a36Sopenharmony_ci */ 41462306a36Sopenharmony_ci uint64_t get_rmt:1; 41562306a36Sopenharmony_ci /* Must be zero */ 41662306a36Sopenharmony_ci uint64_t reserved_0_2:3; 41762306a36Sopenharmony_ci#else 41862306a36Sopenharmony_ci uint64_t reserved_0_2:3; 41962306a36Sopenharmony_ci uint64_t get_rmt:1; 42062306a36Sopenharmony_ci uint64_t get_des_get_tail:1; 42162306a36Sopenharmony_ci uint64_t qosgrp:4; 42262306a36Sopenharmony_ci uint64_t reserved_9_39:31; 42362306a36Sopenharmony_ci uint64_t did:8; 42462306a36Sopenharmony_ci uint64_t is_io:1; 42562306a36Sopenharmony_ci uint64_t reserved_49_61:13; 42662306a36Sopenharmony_ci uint64_t mem_region:2; 42762306a36Sopenharmony_ci#endif 42862306a36Sopenharmony_ci } sindexload; 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci /** 43162306a36Sopenharmony_ci * address for NULL_RD request (did<2:0> == 4) when this is read, 43262306a36Sopenharmony_ci * HW attempts to change the state to NULL if it is NULL_NULL (the 43362306a36Sopenharmony_ci * hardware cannot switch from NULL_NULL to NULL if a POW entry is 43462306a36Sopenharmony_ci * not available - software may need to recover by finishing 43562306a36Sopenharmony_ci * another piece of work before a POW entry can ever become 43662306a36Sopenharmony_ci * available.) 43762306a36Sopenharmony_ci */ 43862306a36Sopenharmony_ci struct { 43962306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 44062306a36Sopenharmony_ci /* Mips64 address region. Should be CVMX_IO_SEG */ 44162306a36Sopenharmony_ci uint64_t mem_region:2; 44262306a36Sopenharmony_ci /* Must be zero */ 44362306a36Sopenharmony_ci uint64_t reserved_49_61:13; 44462306a36Sopenharmony_ci /* Must be one */ 44562306a36Sopenharmony_ci uint64_t is_io:1; 44662306a36Sopenharmony_ci /* the ID of POW -- did<2:0> == 4 in this case */ 44762306a36Sopenharmony_ci uint64_t did:8; 44862306a36Sopenharmony_ci /* Must be zero */ 44962306a36Sopenharmony_ci uint64_t reserved_0_39:40; 45062306a36Sopenharmony_ci#else 45162306a36Sopenharmony_ci uint64_t reserved_0_39:40; 45262306a36Sopenharmony_ci uint64_t did:8; 45362306a36Sopenharmony_ci uint64_t is_io:1; 45462306a36Sopenharmony_ci uint64_t reserved_49_61:13; 45562306a36Sopenharmony_ci uint64_t mem_region:2; 45662306a36Sopenharmony_ci#endif 45762306a36Sopenharmony_ci } snull_rd; 45862306a36Sopenharmony_ci} cvmx_pow_load_addr_t; 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci/** 46162306a36Sopenharmony_ci * This structure defines the response to a load/SENDSINGLE to POW 46262306a36Sopenharmony_ci * (except CSR reads) 46362306a36Sopenharmony_ci */ 46462306a36Sopenharmony_citypedef union { 46562306a36Sopenharmony_ci uint64_t u64; 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci /** 46862306a36Sopenharmony_ci * Response to new work request loads 46962306a36Sopenharmony_ci */ 47062306a36Sopenharmony_ci struct { 47162306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 47262306a36Sopenharmony_ci /* 47362306a36Sopenharmony_ci * Set when no new work queue entry was returned. * 47462306a36Sopenharmony_ci * If there was de-scheduled work, the HW will 47562306a36Sopenharmony_ci * definitely return it. When this bit is set, it 47662306a36Sopenharmony_ci * could mean either mean: 47762306a36Sopenharmony_ci * 47862306a36Sopenharmony_ci * - There was no work, or 47962306a36Sopenharmony_ci * 48062306a36Sopenharmony_ci * - There was no work that the HW could find. This 48162306a36Sopenharmony_ci * case can happen, regardless of the wait bit value 48262306a36Sopenharmony_ci * in the original request, when there is work in 48362306a36Sopenharmony_ci * the IQ's that is too deep down the list. 48462306a36Sopenharmony_ci */ 48562306a36Sopenharmony_ci uint64_t no_work:1; 48662306a36Sopenharmony_ci /* Must be zero */ 48762306a36Sopenharmony_ci uint64_t reserved_40_62:23; 48862306a36Sopenharmony_ci /* 36 in O1 -- the work queue pointer */ 48962306a36Sopenharmony_ci uint64_t addr:40; 49062306a36Sopenharmony_ci#else 49162306a36Sopenharmony_ci uint64_t addr:40; 49262306a36Sopenharmony_ci uint64_t reserved_40_62:23; 49362306a36Sopenharmony_ci uint64_t no_work:1; 49462306a36Sopenharmony_ci#endif 49562306a36Sopenharmony_ci } s_work; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci /** 49862306a36Sopenharmony_ci * Result for a POW Status Load (when get_cur==0 and get_wqp==0) 49962306a36Sopenharmony_ci */ 50062306a36Sopenharmony_ci struct { 50162306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 50262306a36Sopenharmony_ci uint64_t reserved_62_63:2; 50362306a36Sopenharmony_ci /* Set when there is a pending non-NULL SWTAG or 50462306a36Sopenharmony_ci * SWTAG_FULL, and the POW entry has not left the list 50562306a36Sopenharmony_ci * for the original tag. */ 50662306a36Sopenharmony_ci uint64_t pend_switch:1; 50762306a36Sopenharmony_ci /* Set when SWTAG_FULL and pend_switch is set. */ 50862306a36Sopenharmony_ci uint64_t pend_switch_full:1; 50962306a36Sopenharmony_ci /* 51062306a36Sopenharmony_ci * Set when there is a pending NULL SWTAG, or an 51162306a36Sopenharmony_ci * implicit switch to NULL. 51262306a36Sopenharmony_ci */ 51362306a36Sopenharmony_ci uint64_t pend_switch_null:1; 51462306a36Sopenharmony_ci /* Set when there is a pending DESCHED or SWTAG_DESCHED. */ 51562306a36Sopenharmony_ci uint64_t pend_desched:1; 51662306a36Sopenharmony_ci /* 51762306a36Sopenharmony_ci * Set when there is a pending SWTAG_DESCHED and 51862306a36Sopenharmony_ci * pend_desched is set. 51962306a36Sopenharmony_ci */ 52062306a36Sopenharmony_ci uint64_t pend_desched_switch:1; 52162306a36Sopenharmony_ci /* Set when nosched is desired and pend_desched is set. */ 52262306a36Sopenharmony_ci uint64_t pend_nosched:1; 52362306a36Sopenharmony_ci /* Set when there is a pending GET_WORK. */ 52462306a36Sopenharmony_ci uint64_t pend_new_work:1; 52562306a36Sopenharmony_ci /* 52662306a36Sopenharmony_ci * When pend_new_work is set, this bit indicates that 52762306a36Sopenharmony_ci * the wait bit was set. 52862306a36Sopenharmony_ci */ 52962306a36Sopenharmony_ci uint64_t pend_new_work_wait:1; 53062306a36Sopenharmony_ci /* Set when there is a pending NULL_RD. */ 53162306a36Sopenharmony_ci uint64_t pend_null_rd:1; 53262306a36Sopenharmony_ci /* Set when there is a pending CLR_NSCHED. */ 53362306a36Sopenharmony_ci uint64_t pend_nosched_clr:1; 53462306a36Sopenharmony_ci uint64_t reserved_51:1; 53562306a36Sopenharmony_ci /* This is the index when pend_nosched_clr is set. */ 53662306a36Sopenharmony_ci uint64_t pend_index:11; 53762306a36Sopenharmony_ci /* 53862306a36Sopenharmony_ci * This is the new_grp when (pend_desched AND 53962306a36Sopenharmony_ci * pend_desched_switch) is set. 54062306a36Sopenharmony_ci */ 54162306a36Sopenharmony_ci uint64_t pend_grp:4; 54262306a36Sopenharmony_ci uint64_t reserved_34_35:2; 54362306a36Sopenharmony_ci /* 54462306a36Sopenharmony_ci * This is the tag type when pend_switch or 54562306a36Sopenharmony_ci * (pend_desched AND pend_desched_switch) are set. 54662306a36Sopenharmony_ci */ 54762306a36Sopenharmony_ci uint64_t pend_type:2; 54862306a36Sopenharmony_ci /* 54962306a36Sopenharmony_ci * - this is the tag when pend_switch or (pend_desched 55062306a36Sopenharmony_ci * AND pend_desched_switch) are set. 55162306a36Sopenharmony_ci */ 55262306a36Sopenharmony_ci uint64_t pend_tag:32; 55362306a36Sopenharmony_ci#else 55462306a36Sopenharmony_ci uint64_t pend_tag:32; 55562306a36Sopenharmony_ci uint64_t pend_type:2; 55662306a36Sopenharmony_ci uint64_t reserved_34_35:2; 55762306a36Sopenharmony_ci uint64_t pend_grp:4; 55862306a36Sopenharmony_ci uint64_t pend_index:11; 55962306a36Sopenharmony_ci uint64_t reserved_51:1; 56062306a36Sopenharmony_ci uint64_t pend_nosched_clr:1; 56162306a36Sopenharmony_ci uint64_t pend_null_rd:1; 56262306a36Sopenharmony_ci uint64_t pend_new_work_wait:1; 56362306a36Sopenharmony_ci uint64_t pend_new_work:1; 56462306a36Sopenharmony_ci uint64_t pend_nosched:1; 56562306a36Sopenharmony_ci uint64_t pend_desched_switch:1; 56662306a36Sopenharmony_ci uint64_t pend_desched:1; 56762306a36Sopenharmony_ci uint64_t pend_switch_null:1; 56862306a36Sopenharmony_ci uint64_t pend_switch_full:1; 56962306a36Sopenharmony_ci uint64_t pend_switch:1; 57062306a36Sopenharmony_ci uint64_t reserved_62_63:2; 57162306a36Sopenharmony_ci#endif 57262306a36Sopenharmony_ci } s_sstatus0; 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci /** 57562306a36Sopenharmony_ci * Result for a POW Status Load (when get_cur==0 and get_wqp==1) 57662306a36Sopenharmony_ci */ 57762306a36Sopenharmony_ci struct { 57862306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 57962306a36Sopenharmony_ci uint64_t reserved_62_63:2; 58062306a36Sopenharmony_ci /* 58162306a36Sopenharmony_ci * Set when there is a pending non-NULL SWTAG or 58262306a36Sopenharmony_ci * SWTAG_FULL, and the POW entry has not left the list 58362306a36Sopenharmony_ci * for the original tag. 58462306a36Sopenharmony_ci */ 58562306a36Sopenharmony_ci uint64_t pend_switch:1; 58662306a36Sopenharmony_ci /* Set when SWTAG_FULL and pend_switch is set. */ 58762306a36Sopenharmony_ci uint64_t pend_switch_full:1; 58862306a36Sopenharmony_ci /* 58962306a36Sopenharmony_ci * Set when there is a pending NULL SWTAG, or an 59062306a36Sopenharmony_ci * implicit switch to NULL. 59162306a36Sopenharmony_ci */ 59262306a36Sopenharmony_ci uint64_t pend_switch_null:1; 59362306a36Sopenharmony_ci /* 59462306a36Sopenharmony_ci * Set when there is a pending DESCHED or 59562306a36Sopenharmony_ci * SWTAG_DESCHED. 59662306a36Sopenharmony_ci */ 59762306a36Sopenharmony_ci uint64_t pend_desched:1; 59862306a36Sopenharmony_ci /* 59962306a36Sopenharmony_ci * Set when there is a pending SWTAG_DESCHED and 60062306a36Sopenharmony_ci * pend_desched is set. 60162306a36Sopenharmony_ci */ 60262306a36Sopenharmony_ci uint64_t pend_desched_switch:1; 60362306a36Sopenharmony_ci /* Set when nosched is desired and pend_desched is set. */ 60462306a36Sopenharmony_ci uint64_t pend_nosched:1; 60562306a36Sopenharmony_ci /* Set when there is a pending GET_WORK. */ 60662306a36Sopenharmony_ci uint64_t pend_new_work:1; 60762306a36Sopenharmony_ci /* 60862306a36Sopenharmony_ci * When pend_new_work is set, this bit indicates that 60962306a36Sopenharmony_ci * the wait bit was set. 61062306a36Sopenharmony_ci */ 61162306a36Sopenharmony_ci uint64_t pend_new_work_wait:1; 61262306a36Sopenharmony_ci /* Set when there is a pending NULL_RD. */ 61362306a36Sopenharmony_ci uint64_t pend_null_rd:1; 61462306a36Sopenharmony_ci /* Set when there is a pending CLR_NSCHED. */ 61562306a36Sopenharmony_ci uint64_t pend_nosched_clr:1; 61662306a36Sopenharmony_ci uint64_t reserved_51:1; 61762306a36Sopenharmony_ci /* This is the index when pend_nosched_clr is set. */ 61862306a36Sopenharmony_ci uint64_t pend_index:11; 61962306a36Sopenharmony_ci /* 62062306a36Sopenharmony_ci * This is the new_grp when (pend_desched AND 62162306a36Sopenharmony_ci * pend_desched_switch) is set. 62262306a36Sopenharmony_ci */ 62362306a36Sopenharmony_ci uint64_t pend_grp:4; 62462306a36Sopenharmony_ci /* This is the wqp when pend_nosched_clr is set. */ 62562306a36Sopenharmony_ci uint64_t pend_wqp:36; 62662306a36Sopenharmony_ci#else 62762306a36Sopenharmony_ci uint64_t pend_wqp:36; 62862306a36Sopenharmony_ci uint64_t pend_grp:4; 62962306a36Sopenharmony_ci uint64_t pend_index:11; 63062306a36Sopenharmony_ci uint64_t reserved_51:1; 63162306a36Sopenharmony_ci uint64_t pend_nosched_clr:1; 63262306a36Sopenharmony_ci uint64_t pend_null_rd:1; 63362306a36Sopenharmony_ci uint64_t pend_new_work_wait:1; 63462306a36Sopenharmony_ci uint64_t pend_new_work:1; 63562306a36Sopenharmony_ci uint64_t pend_nosched:1; 63662306a36Sopenharmony_ci uint64_t pend_desched_switch:1; 63762306a36Sopenharmony_ci uint64_t pend_desched:1; 63862306a36Sopenharmony_ci uint64_t pend_switch_null:1; 63962306a36Sopenharmony_ci uint64_t pend_switch_full:1; 64062306a36Sopenharmony_ci uint64_t pend_switch:1; 64162306a36Sopenharmony_ci uint64_t reserved_62_63:2; 64262306a36Sopenharmony_ci#endif 64362306a36Sopenharmony_ci } s_sstatus1; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci /** 64662306a36Sopenharmony_ci * Result for a POW Status Load (when get_cur==1, get_wqp==0, and 64762306a36Sopenharmony_ci * get_rev==0) 64862306a36Sopenharmony_ci */ 64962306a36Sopenharmony_ci struct { 65062306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 65162306a36Sopenharmony_ci uint64_t reserved_62_63:2; 65262306a36Sopenharmony_ci /* 65362306a36Sopenharmony_ci * Points to the next POW entry in the tag list when 65462306a36Sopenharmony_ci * tail == 0 (and tag_type is not NULL or NULL_NULL). 65562306a36Sopenharmony_ci */ 65662306a36Sopenharmony_ci uint64_t link_index:11; 65762306a36Sopenharmony_ci /* The POW entry attached to the core. */ 65862306a36Sopenharmony_ci uint64_t index:11; 65962306a36Sopenharmony_ci /* 66062306a36Sopenharmony_ci * The group attached to the core (updated when new 66162306a36Sopenharmony_ci * tag list entered on SWTAG_FULL). 66262306a36Sopenharmony_ci */ 66362306a36Sopenharmony_ci uint64_t grp:4; 66462306a36Sopenharmony_ci /* 66562306a36Sopenharmony_ci * Set when this POW entry is at the head of its tag 66662306a36Sopenharmony_ci * list (also set when in the NULL or NULL_NULL 66762306a36Sopenharmony_ci * state). 66862306a36Sopenharmony_ci */ 66962306a36Sopenharmony_ci uint64_t head:1; 67062306a36Sopenharmony_ci /* 67162306a36Sopenharmony_ci * Set when this POW entry is at the tail of its tag 67262306a36Sopenharmony_ci * list (also set when in the NULL or NULL_NULL 67362306a36Sopenharmony_ci * state). 67462306a36Sopenharmony_ci */ 67562306a36Sopenharmony_ci uint64_t tail:1; 67662306a36Sopenharmony_ci /* 67762306a36Sopenharmony_ci * The tag type attached to the core (updated when new 67862306a36Sopenharmony_ci * tag list entered on SWTAG, SWTAG_FULL, or 67962306a36Sopenharmony_ci * SWTAG_DESCHED). 68062306a36Sopenharmony_ci */ 68162306a36Sopenharmony_ci uint64_t tag_type:2; 68262306a36Sopenharmony_ci /* 68362306a36Sopenharmony_ci * The tag attached to the core (updated when new tag 68462306a36Sopenharmony_ci * list entered on SWTAG, SWTAG_FULL, or 68562306a36Sopenharmony_ci * SWTAG_DESCHED). 68662306a36Sopenharmony_ci */ 68762306a36Sopenharmony_ci uint64_t tag:32; 68862306a36Sopenharmony_ci#else 68962306a36Sopenharmony_ci uint64_t tag:32; 69062306a36Sopenharmony_ci uint64_t tag_type:2; 69162306a36Sopenharmony_ci uint64_t tail:1; 69262306a36Sopenharmony_ci uint64_t head:1; 69362306a36Sopenharmony_ci uint64_t grp:4; 69462306a36Sopenharmony_ci uint64_t index:11; 69562306a36Sopenharmony_ci uint64_t link_index:11; 69662306a36Sopenharmony_ci uint64_t reserved_62_63:2; 69762306a36Sopenharmony_ci#endif 69862306a36Sopenharmony_ci } s_sstatus2; 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci /** 70162306a36Sopenharmony_ci * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1) 70262306a36Sopenharmony_ci */ 70362306a36Sopenharmony_ci struct { 70462306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 70562306a36Sopenharmony_ci uint64_t reserved_62_63:2; 70662306a36Sopenharmony_ci /* 70762306a36Sopenharmony_ci * Points to the prior POW entry in the tag list when 70862306a36Sopenharmony_ci * head == 0 (and tag_type is not NULL or 70962306a36Sopenharmony_ci * NULL_NULL). This field is unpredictable when the 71062306a36Sopenharmony_ci * core's state is NULL or NULL_NULL. 71162306a36Sopenharmony_ci */ 71262306a36Sopenharmony_ci uint64_t revlink_index:11; 71362306a36Sopenharmony_ci /* The POW entry attached to the core. */ 71462306a36Sopenharmony_ci uint64_t index:11; 71562306a36Sopenharmony_ci /* 71662306a36Sopenharmony_ci * The group attached to the core (updated when new 71762306a36Sopenharmony_ci * tag list entered on SWTAG_FULL). 71862306a36Sopenharmony_ci */ 71962306a36Sopenharmony_ci uint64_t grp:4; 72062306a36Sopenharmony_ci /* Set when this POW entry is at the head of its tag 72162306a36Sopenharmony_ci * list (also set when in the NULL or NULL_NULL 72262306a36Sopenharmony_ci * state). 72362306a36Sopenharmony_ci */ 72462306a36Sopenharmony_ci uint64_t head:1; 72562306a36Sopenharmony_ci /* 72662306a36Sopenharmony_ci * Set when this POW entry is at the tail of its tag 72762306a36Sopenharmony_ci * list (also set when in the NULL or NULL_NULL 72862306a36Sopenharmony_ci * state). 72962306a36Sopenharmony_ci */ 73062306a36Sopenharmony_ci uint64_t tail:1; 73162306a36Sopenharmony_ci /* 73262306a36Sopenharmony_ci * The tag type attached to the core (updated when new 73362306a36Sopenharmony_ci * tag list entered on SWTAG, SWTAG_FULL, or 73462306a36Sopenharmony_ci * SWTAG_DESCHED). 73562306a36Sopenharmony_ci */ 73662306a36Sopenharmony_ci uint64_t tag_type:2; 73762306a36Sopenharmony_ci /* 73862306a36Sopenharmony_ci * The tag attached to the core (updated when new tag 73962306a36Sopenharmony_ci * list entered on SWTAG, SWTAG_FULL, or 74062306a36Sopenharmony_ci * SWTAG_DESCHED). 74162306a36Sopenharmony_ci */ 74262306a36Sopenharmony_ci uint64_t tag:32; 74362306a36Sopenharmony_ci#else 74462306a36Sopenharmony_ci uint64_t tag:32; 74562306a36Sopenharmony_ci uint64_t tag_type:2; 74662306a36Sopenharmony_ci uint64_t tail:1; 74762306a36Sopenharmony_ci uint64_t head:1; 74862306a36Sopenharmony_ci uint64_t grp:4; 74962306a36Sopenharmony_ci uint64_t index:11; 75062306a36Sopenharmony_ci uint64_t revlink_index:11; 75162306a36Sopenharmony_ci uint64_t reserved_62_63:2; 75262306a36Sopenharmony_ci#endif 75362306a36Sopenharmony_ci } s_sstatus3; 75462306a36Sopenharmony_ci 75562306a36Sopenharmony_ci /** 75662306a36Sopenharmony_ci * Result for a POW Status Load (when get_cur==1, get_wqp==1, and 75762306a36Sopenharmony_ci * get_rev==0) 75862306a36Sopenharmony_ci */ 75962306a36Sopenharmony_ci struct { 76062306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 76162306a36Sopenharmony_ci uint64_t reserved_62_63:2; 76262306a36Sopenharmony_ci /* 76362306a36Sopenharmony_ci * Points to the next POW entry in the tag list when 76462306a36Sopenharmony_ci * tail == 0 (and tag_type is not NULL or NULL_NULL). 76562306a36Sopenharmony_ci */ 76662306a36Sopenharmony_ci uint64_t link_index:11; 76762306a36Sopenharmony_ci /* The POW entry attached to the core. */ 76862306a36Sopenharmony_ci uint64_t index:11; 76962306a36Sopenharmony_ci /* 77062306a36Sopenharmony_ci * The group attached to the core (updated when new 77162306a36Sopenharmony_ci * tag list entered on SWTAG_FULL). 77262306a36Sopenharmony_ci */ 77362306a36Sopenharmony_ci uint64_t grp:4; 77462306a36Sopenharmony_ci /* 77562306a36Sopenharmony_ci * The wqp attached to the core (updated when new tag 77662306a36Sopenharmony_ci * list entered on SWTAG_FULL). 77762306a36Sopenharmony_ci */ 77862306a36Sopenharmony_ci uint64_t wqp:36; 77962306a36Sopenharmony_ci#else 78062306a36Sopenharmony_ci uint64_t wqp:36; 78162306a36Sopenharmony_ci uint64_t grp:4; 78262306a36Sopenharmony_ci uint64_t index:11; 78362306a36Sopenharmony_ci uint64_t link_index:11; 78462306a36Sopenharmony_ci uint64_t reserved_62_63:2; 78562306a36Sopenharmony_ci#endif 78662306a36Sopenharmony_ci } s_sstatus4; 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci /** 78962306a36Sopenharmony_ci * Result for a POW Status Load (when get_cur==1, get_wqp==1, and 79062306a36Sopenharmony_ci * get_rev==1) 79162306a36Sopenharmony_ci */ 79262306a36Sopenharmony_ci struct { 79362306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 79462306a36Sopenharmony_ci uint64_t reserved_62_63:2; 79562306a36Sopenharmony_ci /* 79662306a36Sopenharmony_ci * Points to the prior POW entry in the tag list when 79762306a36Sopenharmony_ci * head == 0 (and tag_type is not NULL or 79862306a36Sopenharmony_ci * NULL_NULL). This field is unpredictable when the 79962306a36Sopenharmony_ci * core's state is NULL or NULL_NULL. 80062306a36Sopenharmony_ci */ 80162306a36Sopenharmony_ci uint64_t revlink_index:11; 80262306a36Sopenharmony_ci /* The POW entry attached to the core. */ 80362306a36Sopenharmony_ci uint64_t index:11; 80462306a36Sopenharmony_ci /* 80562306a36Sopenharmony_ci * The group attached to the core (updated when new 80662306a36Sopenharmony_ci * tag list entered on SWTAG_FULL). 80762306a36Sopenharmony_ci */ 80862306a36Sopenharmony_ci uint64_t grp:4; 80962306a36Sopenharmony_ci /* 81062306a36Sopenharmony_ci * The wqp attached to the core (updated when new tag 81162306a36Sopenharmony_ci * list entered on SWTAG_FULL). 81262306a36Sopenharmony_ci */ 81362306a36Sopenharmony_ci uint64_t wqp:36; 81462306a36Sopenharmony_ci#else 81562306a36Sopenharmony_ci uint64_t wqp:36; 81662306a36Sopenharmony_ci uint64_t grp:4; 81762306a36Sopenharmony_ci uint64_t index:11; 81862306a36Sopenharmony_ci uint64_t revlink_index:11; 81962306a36Sopenharmony_ci uint64_t reserved_62_63:2; 82062306a36Sopenharmony_ci#endif 82162306a36Sopenharmony_ci } s_sstatus5; 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_ci /** 82462306a36Sopenharmony_ci * Result For POW Memory Load (get_des == 0 and get_wqp == 0) 82562306a36Sopenharmony_ci */ 82662306a36Sopenharmony_ci struct { 82762306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 82862306a36Sopenharmony_ci uint64_t reserved_51_63:13; 82962306a36Sopenharmony_ci /* 83062306a36Sopenharmony_ci * The next entry in the input, free, descheduled_head 83162306a36Sopenharmony_ci * list (unpredictable if entry is the tail of the 83262306a36Sopenharmony_ci * list). 83362306a36Sopenharmony_ci */ 83462306a36Sopenharmony_ci uint64_t next_index:11; 83562306a36Sopenharmony_ci /* The group of the POW entry. */ 83662306a36Sopenharmony_ci uint64_t grp:4; 83762306a36Sopenharmony_ci uint64_t reserved_35:1; 83862306a36Sopenharmony_ci /* 83962306a36Sopenharmony_ci * Set when this POW entry is at the tail of its tag 84062306a36Sopenharmony_ci * list (also set when in the NULL or NULL_NULL 84162306a36Sopenharmony_ci * state). 84262306a36Sopenharmony_ci */ 84362306a36Sopenharmony_ci uint64_t tail:1; 84462306a36Sopenharmony_ci /* The tag type of the POW entry. */ 84562306a36Sopenharmony_ci uint64_t tag_type:2; 84662306a36Sopenharmony_ci /* The tag of the POW entry. */ 84762306a36Sopenharmony_ci uint64_t tag:32; 84862306a36Sopenharmony_ci#else 84962306a36Sopenharmony_ci uint64_t tag:32; 85062306a36Sopenharmony_ci uint64_t tag_type:2; 85162306a36Sopenharmony_ci uint64_t tail:1; 85262306a36Sopenharmony_ci uint64_t reserved_35:1; 85362306a36Sopenharmony_ci uint64_t grp:4; 85462306a36Sopenharmony_ci uint64_t next_index:11; 85562306a36Sopenharmony_ci uint64_t reserved_51_63:13; 85662306a36Sopenharmony_ci#endif 85762306a36Sopenharmony_ci } s_smemload0; 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci /** 86062306a36Sopenharmony_ci * Result For POW Memory Load (get_des == 0 and get_wqp == 1) 86162306a36Sopenharmony_ci */ 86262306a36Sopenharmony_ci struct { 86362306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 86462306a36Sopenharmony_ci uint64_t reserved_51_63:13; 86562306a36Sopenharmony_ci /* 86662306a36Sopenharmony_ci * The next entry in the input, free, descheduled_head 86762306a36Sopenharmony_ci * list (unpredictable if entry is the tail of the 86862306a36Sopenharmony_ci * list). 86962306a36Sopenharmony_ci */ 87062306a36Sopenharmony_ci uint64_t next_index:11; 87162306a36Sopenharmony_ci /* The group of the POW entry. */ 87262306a36Sopenharmony_ci uint64_t grp:4; 87362306a36Sopenharmony_ci /* The WQP held in the POW entry. */ 87462306a36Sopenharmony_ci uint64_t wqp:36; 87562306a36Sopenharmony_ci#else 87662306a36Sopenharmony_ci uint64_t wqp:36; 87762306a36Sopenharmony_ci uint64_t grp:4; 87862306a36Sopenharmony_ci uint64_t next_index:11; 87962306a36Sopenharmony_ci uint64_t reserved_51_63:13; 88062306a36Sopenharmony_ci#endif 88162306a36Sopenharmony_ci } s_smemload1; 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci /** 88462306a36Sopenharmony_ci * Result For POW Memory Load (get_des == 1) 88562306a36Sopenharmony_ci */ 88662306a36Sopenharmony_ci struct { 88762306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 88862306a36Sopenharmony_ci uint64_t reserved_51_63:13; 88962306a36Sopenharmony_ci /* 89062306a36Sopenharmony_ci * The next entry in the tag list connected to the 89162306a36Sopenharmony_ci * descheduled head. 89262306a36Sopenharmony_ci */ 89362306a36Sopenharmony_ci uint64_t fwd_index:11; 89462306a36Sopenharmony_ci /* The group of the POW entry. */ 89562306a36Sopenharmony_ci uint64_t grp:4; 89662306a36Sopenharmony_ci /* The nosched bit for the POW entry. */ 89762306a36Sopenharmony_ci uint64_t nosched:1; 89862306a36Sopenharmony_ci /* There is a pending tag switch */ 89962306a36Sopenharmony_ci uint64_t pend_switch:1; 90062306a36Sopenharmony_ci /* 90162306a36Sopenharmony_ci * The next tag type for the new tag list when 90262306a36Sopenharmony_ci * pend_switch is set. 90362306a36Sopenharmony_ci */ 90462306a36Sopenharmony_ci uint64_t pend_type:2; 90562306a36Sopenharmony_ci /* 90662306a36Sopenharmony_ci * The next tag for the new tag list when pend_switch 90762306a36Sopenharmony_ci * is set. 90862306a36Sopenharmony_ci */ 90962306a36Sopenharmony_ci uint64_t pend_tag:32; 91062306a36Sopenharmony_ci#else 91162306a36Sopenharmony_ci uint64_t pend_tag:32; 91262306a36Sopenharmony_ci uint64_t pend_type:2; 91362306a36Sopenharmony_ci uint64_t pend_switch:1; 91462306a36Sopenharmony_ci uint64_t nosched:1; 91562306a36Sopenharmony_ci uint64_t grp:4; 91662306a36Sopenharmony_ci uint64_t fwd_index:11; 91762306a36Sopenharmony_ci uint64_t reserved_51_63:13; 91862306a36Sopenharmony_ci#endif 91962306a36Sopenharmony_ci } s_smemload2; 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci /** 92262306a36Sopenharmony_ci * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0) 92362306a36Sopenharmony_ci */ 92462306a36Sopenharmony_ci struct { 92562306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 92662306a36Sopenharmony_ci uint64_t reserved_52_63:12; 92762306a36Sopenharmony_ci /* 92862306a36Sopenharmony_ci * set when there is one or more POW entries on the 92962306a36Sopenharmony_ci * free list. 93062306a36Sopenharmony_ci */ 93162306a36Sopenharmony_ci uint64_t free_val:1; 93262306a36Sopenharmony_ci /* 93362306a36Sopenharmony_ci * set when there is exactly one POW entry on the free 93462306a36Sopenharmony_ci * list. 93562306a36Sopenharmony_ci */ 93662306a36Sopenharmony_ci uint64_t free_one:1; 93762306a36Sopenharmony_ci uint64_t reserved_49:1; 93862306a36Sopenharmony_ci /* 93962306a36Sopenharmony_ci * when free_val is set, indicates the first entry on 94062306a36Sopenharmony_ci * the free list. 94162306a36Sopenharmony_ci */ 94262306a36Sopenharmony_ci uint64_t free_head:11; 94362306a36Sopenharmony_ci uint64_t reserved_37:1; 94462306a36Sopenharmony_ci /* 94562306a36Sopenharmony_ci * when free_val is set, indicates the last entry on 94662306a36Sopenharmony_ci * the free list. 94762306a36Sopenharmony_ci */ 94862306a36Sopenharmony_ci uint64_t free_tail:11; 94962306a36Sopenharmony_ci /* 95062306a36Sopenharmony_ci * set when there is one or more POW entries on the 95162306a36Sopenharmony_ci * input Q list selected by qosgrp. 95262306a36Sopenharmony_ci */ 95362306a36Sopenharmony_ci uint64_t loc_val:1; 95462306a36Sopenharmony_ci /* 95562306a36Sopenharmony_ci * set when there is exactly one POW entry on the 95662306a36Sopenharmony_ci * input Q list selected by qosgrp. 95762306a36Sopenharmony_ci */ 95862306a36Sopenharmony_ci uint64_t loc_one:1; 95962306a36Sopenharmony_ci uint64_t reserved_23:1; 96062306a36Sopenharmony_ci /* 96162306a36Sopenharmony_ci * when loc_val is set, indicates the first entry on 96262306a36Sopenharmony_ci * the input Q list selected by qosgrp. 96362306a36Sopenharmony_ci */ 96462306a36Sopenharmony_ci uint64_t loc_head:11; 96562306a36Sopenharmony_ci uint64_t reserved_11:1; 96662306a36Sopenharmony_ci /* 96762306a36Sopenharmony_ci * when loc_val is set, indicates the last entry on 96862306a36Sopenharmony_ci * the input Q list selected by qosgrp. 96962306a36Sopenharmony_ci */ 97062306a36Sopenharmony_ci uint64_t loc_tail:11; 97162306a36Sopenharmony_ci#else 97262306a36Sopenharmony_ci uint64_t loc_tail:11; 97362306a36Sopenharmony_ci uint64_t reserved_11:1; 97462306a36Sopenharmony_ci uint64_t loc_head:11; 97562306a36Sopenharmony_ci uint64_t reserved_23:1; 97662306a36Sopenharmony_ci uint64_t loc_one:1; 97762306a36Sopenharmony_ci uint64_t loc_val:1; 97862306a36Sopenharmony_ci uint64_t free_tail:11; 97962306a36Sopenharmony_ci uint64_t reserved_37:1; 98062306a36Sopenharmony_ci uint64_t free_head:11; 98162306a36Sopenharmony_ci uint64_t reserved_49:1; 98262306a36Sopenharmony_ci uint64_t free_one:1; 98362306a36Sopenharmony_ci uint64_t free_val:1; 98462306a36Sopenharmony_ci uint64_t reserved_52_63:12; 98562306a36Sopenharmony_ci#endif 98662306a36Sopenharmony_ci } sindexload0; 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci /** 98962306a36Sopenharmony_ci * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1) 99062306a36Sopenharmony_ci */ 99162306a36Sopenharmony_ci struct { 99262306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 99362306a36Sopenharmony_ci uint64_t reserved_52_63:12; 99462306a36Sopenharmony_ci /* 99562306a36Sopenharmony_ci * set when there is one or more POW entries on the 99662306a36Sopenharmony_ci * nosched list. 99762306a36Sopenharmony_ci */ 99862306a36Sopenharmony_ci uint64_t nosched_val:1; 99962306a36Sopenharmony_ci /* 100062306a36Sopenharmony_ci * set when there is exactly one POW entry on the 100162306a36Sopenharmony_ci * nosched list. 100262306a36Sopenharmony_ci */ 100362306a36Sopenharmony_ci uint64_t nosched_one:1; 100462306a36Sopenharmony_ci uint64_t reserved_49:1; 100562306a36Sopenharmony_ci /* 100662306a36Sopenharmony_ci * when nosched_val is set, indicates the first entry 100762306a36Sopenharmony_ci * on the nosched list. 100862306a36Sopenharmony_ci */ 100962306a36Sopenharmony_ci uint64_t nosched_head:11; 101062306a36Sopenharmony_ci uint64_t reserved_37:1; 101162306a36Sopenharmony_ci /* 101262306a36Sopenharmony_ci * when nosched_val is set, indicates the last entry 101362306a36Sopenharmony_ci * on the nosched list. 101462306a36Sopenharmony_ci */ 101562306a36Sopenharmony_ci uint64_t nosched_tail:11; 101662306a36Sopenharmony_ci /* 101762306a36Sopenharmony_ci * set when there is one or more descheduled heads on 101862306a36Sopenharmony_ci * the descheduled list selected by qosgrp. 101962306a36Sopenharmony_ci */ 102062306a36Sopenharmony_ci uint64_t des_val:1; 102162306a36Sopenharmony_ci /* 102262306a36Sopenharmony_ci * set when there is exactly one descheduled head on 102362306a36Sopenharmony_ci * the descheduled list selected by qosgrp. 102462306a36Sopenharmony_ci */ 102562306a36Sopenharmony_ci uint64_t des_one:1; 102662306a36Sopenharmony_ci uint64_t reserved_23:1; 102762306a36Sopenharmony_ci /* 102862306a36Sopenharmony_ci * when des_val is set, indicates the first 102962306a36Sopenharmony_ci * descheduled head on the descheduled list selected 103062306a36Sopenharmony_ci * by qosgrp. 103162306a36Sopenharmony_ci */ 103262306a36Sopenharmony_ci uint64_t des_head:11; 103362306a36Sopenharmony_ci uint64_t reserved_11:1; 103462306a36Sopenharmony_ci /* 103562306a36Sopenharmony_ci * when des_val is set, indicates the last descheduled 103662306a36Sopenharmony_ci * head on the descheduled list selected by qosgrp. 103762306a36Sopenharmony_ci */ 103862306a36Sopenharmony_ci uint64_t des_tail:11; 103962306a36Sopenharmony_ci#else 104062306a36Sopenharmony_ci uint64_t des_tail:11; 104162306a36Sopenharmony_ci uint64_t reserved_11:1; 104262306a36Sopenharmony_ci uint64_t des_head:11; 104362306a36Sopenharmony_ci uint64_t reserved_23:1; 104462306a36Sopenharmony_ci uint64_t des_one:1; 104562306a36Sopenharmony_ci uint64_t des_val:1; 104662306a36Sopenharmony_ci uint64_t nosched_tail:11; 104762306a36Sopenharmony_ci uint64_t reserved_37:1; 104862306a36Sopenharmony_ci uint64_t nosched_head:11; 104962306a36Sopenharmony_ci uint64_t reserved_49:1; 105062306a36Sopenharmony_ci uint64_t nosched_one:1; 105162306a36Sopenharmony_ci uint64_t nosched_val:1; 105262306a36Sopenharmony_ci uint64_t reserved_52_63:12; 105362306a36Sopenharmony_ci#endif 105462306a36Sopenharmony_ci } sindexload1; 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci /** 105762306a36Sopenharmony_ci * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0) 105862306a36Sopenharmony_ci */ 105962306a36Sopenharmony_ci struct { 106062306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 106162306a36Sopenharmony_ci uint64_t reserved_39_63:25; 106262306a36Sopenharmony_ci /* 106362306a36Sopenharmony_ci * Set when this DRAM list is the current head 106462306a36Sopenharmony_ci * (i.e. is the next to be reloaded when the POW 106562306a36Sopenharmony_ci * hardware reloads a POW entry from DRAM). The POW 106662306a36Sopenharmony_ci * hardware alternates between the two DRAM lists 106762306a36Sopenharmony_ci * associated with a QOS level when it reloads work 106862306a36Sopenharmony_ci * from DRAM into the POW unit. 106962306a36Sopenharmony_ci */ 107062306a36Sopenharmony_ci uint64_t rmt_is_head:1; 107162306a36Sopenharmony_ci /* 107262306a36Sopenharmony_ci * Set when the DRAM portion of the input Q list 107362306a36Sopenharmony_ci * selected by qosgrp contains one or more pieces of 107462306a36Sopenharmony_ci * work. 107562306a36Sopenharmony_ci */ 107662306a36Sopenharmony_ci uint64_t rmt_val:1; 107762306a36Sopenharmony_ci /* 107862306a36Sopenharmony_ci * Set when the DRAM portion of the input Q list 107962306a36Sopenharmony_ci * selected by qosgrp contains exactly one piece of 108062306a36Sopenharmony_ci * work. 108162306a36Sopenharmony_ci */ 108262306a36Sopenharmony_ci uint64_t rmt_one:1; 108362306a36Sopenharmony_ci /* 108462306a36Sopenharmony_ci * When rmt_val is set, indicates the first piece of 108562306a36Sopenharmony_ci * work on the DRAM input Q list selected by 108662306a36Sopenharmony_ci * qosgrp. 108762306a36Sopenharmony_ci */ 108862306a36Sopenharmony_ci uint64_t rmt_head:36; 108962306a36Sopenharmony_ci#else 109062306a36Sopenharmony_ci uint64_t rmt_head:36; 109162306a36Sopenharmony_ci uint64_t rmt_one:1; 109262306a36Sopenharmony_ci uint64_t rmt_val:1; 109362306a36Sopenharmony_ci uint64_t rmt_is_head:1; 109462306a36Sopenharmony_ci uint64_t reserved_39_63:25; 109562306a36Sopenharmony_ci#endif 109662306a36Sopenharmony_ci } sindexload2; 109762306a36Sopenharmony_ci 109862306a36Sopenharmony_ci /** 109962306a36Sopenharmony_ci * Result For POW Index/Pointer Load (get_rmt == 110062306a36Sopenharmony_ci * 1/get_des_get_tail == 1) 110162306a36Sopenharmony_ci */ 110262306a36Sopenharmony_ci struct { 110362306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 110462306a36Sopenharmony_ci uint64_t reserved_39_63:25; 110562306a36Sopenharmony_ci /* 110662306a36Sopenharmony_ci * set when this DRAM list is the current head 110762306a36Sopenharmony_ci * (i.e. is the next to be reloaded when the POW 110862306a36Sopenharmony_ci * hardware reloads a POW entry from DRAM). The POW 110962306a36Sopenharmony_ci * hardware alternates between the two DRAM lists 111062306a36Sopenharmony_ci * associated with a QOS level when it reloads work 111162306a36Sopenharmony_ci * from DRAM into the POW unit. 111262306a36Sopenharmony_ci */ 111362306a36Sopenharmony_ci uint64_t rmt_is_head:1; 111462306a36Sopenharmony_ci /* 111562306a36Sopenharmony_ci * set when the DRAM portion of the input Q list 111662306a36Sopenharmony_ci * selected by qosgrp contains one or more pieces of 111762306a36Sopenharmony_ci * work. 111862306a36Sopenharmony_ci */ 111962306a36Sopenharmony_ci uint64_t rmt_val:1; 112062306a36Sopenharmony_ci /* 112162306a36Sopenharmony_ci * set when the DRAM portion of the input Q list 112262306a36Sopenharmony_ci * selected by qosgrp contains exactly one piece of 112362306a36Sopenharmony_ci * work. 112462306a36Sopenharmony_ci */ 112562306a36Sopenharmony_ci uint64_t rmt_one:1; 112662306a36Sopenharmony_ci /* 112762306a36Sopenharmony_ci * when rmt_val is set, indicates the last piece of 112862306a36Sopenharmony_ci * work on the DRAM input Q list selected by 112962306a36Sopenharmony_ci * qosgrp. 113062306a36Sopenharmony_ci */ 113162306a36Sopenharmony_ci uint64_t rmt_tail:36; 113262306a36Sopenharmony_ci#else 113362306a36Sopenharmony_ci uint64_t rmt_tail:36; 113462306a36Sopenharmony_ci uint64_t rmt_one:1; 113562306a36Sopenharmony_ci uint64_t rmt_val:1; 113662306a36Sopenharmony_ci uint64_t rmt_is_head:1; 113762306a36Sopenharmony_ci uint64_t reserved_39_63:25; 113862306a36Sopenharmony_ci#endif 113962306a36Sopenharmony_ci } sindexload3; 114062306a36Sopenharmony_ci 114162306a36Sopenharmony_ci /** 114262306a36Sopenharmony_ci * Response to NULL_RD request loads 114362306a36Sopenharmony_ci */ 114462306a36Sopenharmony_ci struct { 114562306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 114662306a36Sopenharmony_ci uint64_t unused:62; 114762306a36Sopenharmony_ci /* of type cvmx_pow_tag_type_t. state is one of the 114862306a36Sopenharmony_ci * following: 114962306a36Sopenharmony_ci * 115062306a36Sopenharmony_ci * - CVMX_POW_TAG_TYPE_ORDERED 115162306a36Sopenharmony_ci * - CVMX_POW_TAG_TYPE_ATOMIC 115262306a36Sopenharmony_ci * - CVMX_POW_TAG_TYPE_NULL 115362306a36Sopenharmony_ci * - CVMX_POW_TAG_TYPE_NULL_NULL 115462306a36Sopenharmony_ci */ 115562306a36Sopenharmony_ci uint64_t state:2; 115662306a36Sopenharmony_ci#else 115762306a36Sopenharmony_ci uint64_t state:2; 115862306a36Sopenharmony_ci uint64_t unused:62; 115962306a36Sopenharmony_ci#endif 116062306a36Sopenharmony_ci } s_null_rd; 116162306a36Sopenharmony_ci 116262306a36Sopenharmony_ci} cvmx_pow_tag_load_resp_t; 116362306a36Sopenharmony_ci 116462306a36Sopenharmony_ci/** 116562306a36Sopenharmony_ci * This structure describes the address used for stores to the POW. 116662306a36Sopenharmony_ci * The store address is meaningful on stores to the POW. The 116762306a36Sopenharmony_ci * hardware assumes that an aligned 64-bit store was used for all 116862306a36Sopenharmony_ci * these stores. Note the assumption that the work queue entry is 116962306a36Sopenharmony_ci * aligned on an 8-byte boundary (since the low-order 3 address bits 117062306a36Sopenharmony_ci * must be zero). Note that not all fields are used by all 117162306a36Sopenharmony_ci * operations. 117262306a36Sopenharmony_ci * 117362306a36Sopenharmony_ci * NOTE: The following is the behavior of the pending switch bit at the PP 117462306a36Sopenharmony_ci * for POW stores (i.e. when did<7:3> == 0xc) 117562306a36Sopenharmony_ci * - did<2:0> == 0 => pending switch bit is set 117662306a36Sopenharmony_ci * - did<2:0> == 1 => no affect on the pending switch bit 117762306a36Sopenharmony_ci * - did<2:0> == 3 => pending switch bit is cleared 117862306a36Sopenharmony_ci * - did<2:0> == 7 => no affect on the pending switch bit 117962306a36Sopenharmony_ci * - did<2:0> == others => must not be used 118062306a36Sopenharmony_ci * - No other loads/stores have an affect on the pending switch bit 118162306a36Sopenharmony_ci * - The switch bus from POW can clear the pending switch bit 118262306a36Sopenharmony_ci * 118362306a36Sopenharmony_ci * NOTE: did<2:0> == 2 is used by the HW for a special single-cycle 118462306a36Sopenharmony_ci * ADDWQ command that only contains the pointer). SW must never use 118562306a36Sopenharmony_ci * did<2:0> == 2. 118662306a36Sopenharmony_ci */ 118762306a36Sopenharmony_citypedef union { 118862306a36Sopenharmony_ci /** 118962306a36Sopenharmony_ci * Unsigned 64 bit integer representation of store address 119062306a36Sopenharmony_ci */ 119162306a36Sopenharmony_ci uint64_t u64; 119262306a36Sopenharmony_ci 119362306a36Sopenharmony_ci struct { 119462306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 119562306a36Sopenharmony_ci /* Memory region. Should be CVMX_IO_SEG in most cases */ 119662306a36Sopenharmony_ci uint64_t mem_reg:2; 119762306a36Sopenharmony_ci uint64_t reserved_49_61:13; /* Must be zero */ 119862306a36Sopenharmony_ci uint64_t is_io:1; /* Must be one */ 119962306a36Sopenharmony_ci /* Device ID of POW. Note that different sub-dids are used. */ 120062306a36Sopenharmony_ci uint64_t did:8; 120162306a36Sopenharmony_ci uint64_t reserved_36_39:4; /* Must be zero */ 120262306a36Sopenharmony_ci /* Address field. addr<2:0> must be zero */ 120362306a36Sopenharmony_ci uint64_t addr:36; 120462306a36Sopenharmony_ci#else 120562306a36Sopenharmony_ci uint64_t addr:36; 120662306a36Sopenharmony_ci uint64_t reserved_36_39:4; 120762306a36Sopenharmony_ci uint64_t did:8; 120862306a36Sopenharmony_ci uint64_t is_io:1; 120962306a36Sopenharmony_ci uint64_t reserved_49_61:13; 121062306a36Sopenharmony_ci uint64_t mem_reg:2; 121162306a36Sopenharmony_ci#endif 121262306a36Sopenharmony_ci } stag; 121362306a36Sopenharmony_ci} cvmx_pow_tag_store_addr_t; 121462306a36Sopenharmony_ci 121562306a36Sopenharmony_ci/** 121662306a36Sopenharmony_ci * decode of the store data when an IOBDMA SENDSINGLE is sent to POW 121762306a36Sopenharmony_ci */ 121862306a36Sopenharmony_citypedef union { 121962306a36Sopenharmony_ci uint64_t u64; 122062306a36Sopenharmony_ci 122162306a36Sopenharmony_ci struct { 122262306a36Sopenharmony_ci#ifdef __BIG_ENDIAN_BITFIELD 122362306a36Sopenharmony_ci /* 122462306a36Sopenharmony_ci * the (64-bit word) location in scratchpad to write 122562306a36Sopenharmony_ci * to (if len != 0) 122662306a36Sopenharmony_ci */ 122762306a36Sopenharmony_ci uint64_t scraddr:8; 122862306a36Sopenharmony_ci /* the number of words in the response (0 => no response) */ 122962306a36Sopenharmony_ci uint64_t len:8; 123062306a36Sopenharmony_ci /* the ID of the device on the non-coherent bus */ 123162306a36Sopenharmony_ci uint64_t did:8; 123262306a36Sopenharmony_ci uint64_t unused:36; 123362306a36Sopenharmony_ci /* if set, don't return load response until work is available */ 123462306a36Sopenharmony_ci uint64_t wait:1; 123562306a36Sopenharmony_ci uint64_t unused2:3; 123662306a36Sopenharmony_ci#else 123762306a36Sopenharmony_ci uint64_t unused2:3; 123862306a36Sopenharmony_ci uint64_t wait:1; 123962306a36Sopenharmony_ci uint64_t unused:36; 124062306a36Sopenharmony_ci uint64_t did:8; 124162306a36Sopenharmony_ci uint64_t len:8; 124262306a36Sopenharmony_ci uint64_t scraddr:8; 124362306a36Sopenharmony_ci#endif 124462306a36Sopenharmony_ci } s; 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_ci} cvmx_pow_iobdma_store_t; 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci/* CSR typedefs have been moved to cvmx-csr-*.h */ 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_ci/** 125162306a36Sopenharmony_ci * Get the POW tag for this core. This returns the current 125262306a36Sopenharmony_ci * tag type, tag, group, and POW entry index associated with 125362306a36Sopenharmony_ci * this core. Index is only valid if the tag type isn't NULL_NULL. 125462306a36Sopenharmony_ci * If a tag switch is pending this routine returns the tag before 125562306a36Sopenharmony_ci * the tag switch, not after. 125662306a36Sopenharmony_ci * 125762306a36Sopenharmony_ci * Returns Current tag 125862306a36Sopenharmony_ci */ 125962306a36Sopenharmony_cistatic inline cvmx_pow_tag_req_t cvmx_pow_get_current_tag(void) 126062306a36Sopenharmony_ci{ 126162306a36Sopenharmony_ci cvmx_pow_load_addr_t load_addr; 126262306a36Sopenharmony_ci cvmx_pow_tag_load_resp_t load_resp; 126362306a36Sopenharmony_ci cvmx_pow_tag_req_t result; 126462306a36Sopenharmony_ci 126562306a36Sopenharmony_ci load_addr.u64 = 0; 126662306a36Sopenharmony_ci load_addr.sstatus.mem_region = CVMX_IO_SEG; 126762306a36Sopenharmony_ci load_addr.sstatus.is_io = 1; 126862306a36Sopenharmony_ci load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1; 126962306a36Sopenharmony_ci load_addr.sstatus.coreid = cvmx_get_core_num(); 127062306a36Sopenharmony_ci load_addr.sstatus.get_cur = 1; 127162306a36Sopenharmony_ci load_resp.u64 = cvmx_read_csr(load_addr.u64); 127262306a36Sopenharmony_ci result.u64 = 0; 127362306a36Sopenharmony_ci result.s.grp = load_resp.s_sstatus2.grp; 127462306a36Sopenharmony_ci result.s.index = load_resp.s_sstatus2.index; 127562306a36Sopenharmony_ci result.s.type = load_resp.s_sstatus2.tag_type; 127662306a36Sopenharmony_ci result.s.tag = load_resp.s_sstatus2.tag; 127762306a36Sopenharmony_ci return result; 127862306a36Sopenharmony_ci} 127962306a36Sopenharmony_ci 128062306a36Sopenharmony_ci/** 128162306a36Sopenharmony_ci * Get the POW WQE for this core. This returns the work queue 128262306a36Sopenharmony_ci * entry currently associated with this core. 128362306a36Sopenharmony_ci * 128462306a36Sopenharmony_ci * Returns WQE pointer 128562306a36Sopenharmony_ci */ 128662306a36Sopenharmony_cistatic inline struct cvmx_wqe *cvmx_pow_get_current_wqp(void) 128762306a36Sopenharmony_ci{ 128862306a36Sopenharmony_ci cvmx_pow_load_addr_t load_addr; 128962306a36Sopenharmony_ci cvmx_pow_tag_load_resp_t load_resp; 129062306a36Sopenharmony_ci 129162306a36Sopenharmony_ci load_addr.u64 = 0; 129262306a36Sopenharmony_ci load_addr.sstatus.mem_region = CVMX_IO_SEG; 129362306a36Sopenharmony_ci load_addr.sstatus.is_io = 1; 129462306a36Sopenharmony_ci load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1; 129562306a36Sopenharmony_ci load_addr.sstatus.coreid = cvmx_get_core_num(); 129662306a36Sopenharmony_ci load_addr.sstatus.get_cur = 1; 129762306a36Sopenharmony_ci load_addr.sstatus.get_wqp = 1; 129862306a36Sopenharmony_ci load_resp.u64 = cvmx_read_csr(load_addr.u64); 129962306a36Sopenharmony_ci return (struct cvmx_wqe *) cvmx_phys_to_ptr(load_resp.s_sstatus4.wqp); 130062306a36Sopenharmony_ci} 130162306a36Sopenharmony_ci 130262306a36Sopenharmony_ci#ifndef CVMX_MF_CHORD 130362306a36Sopenharmony_ci#define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30) 130462306a36Sopenharmony_ci#endif 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci/** 130762306a36Sopenharmony_ci * Print a warning if a tag switch is pending for this core 130862306a36Sopenharmony_ci * 130962306a36Sopenharmony_ci * @function: Function name checking for a pending tag switch 131062306a36Sopenharmony_ci */ 131162306a36Sopenharmony_cistatic inline void __cvmx_pow_warn_if_pending_switch(const char *function) 131262306a36Sopenharmony_ci{ 131362306a36Sopenharmony_ci uint64_t switch_complete; 131462306a36Sopenharmony_ci CVMX_MF_CHORD(switch_complete); 131562306a36Sopenharmony_ci if (!switch_complete) 131662306a36Sopenharmony_ci pr_warn("%s called with tag switch in progress\n", function); 131762306a36Sopenharmony_ci} 131862306a36Sopenharmony_ci 131962306a36Sopenharmony_ci/** 132062306a36Sopenharmony_ci * Waits for a tag switch to complete by polling the completion bit. 132162306a36Sopenharmony_ci * Note that switches to NULL complete immediately and do not need 132262306a36Sopenharmony_ci * to be waited for. 132362306a36Sopenharmony_ci */ 132462306a36Sopenharmony_cistatic inline void cvmx_pow_tag_sw_wait(void) 132562306a36Sopenharmony_ci{ 132662306a36Sopenharmony_ci const uint64_t MAX_CYCLES = 1ull << 31; 132762306a36Sopenharmony_ci uint64_t switch_complete; 132862306a36Sopenharmony_ci uint64_t start_cycle = cvmx_get_cycle(); 132962306a36Sopenharmony_ci while (1) { 133062306a36Sopenharmony_ci CVMX_MF_CHORD(switch_complete); 133162306a36Sopenharmony_ci if (unlikely(switch_complete)) 133262306a36Sopenharmony_ci break; 133362306a36Sopenharmony_ci if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { 133462306a36Sopenharmony_ci pr_warn("Tag switch is taking a long time, possible deadlock\n"); 133562306a36Sopenharmony_ci start_cycle = -MAX_CYCLES - 1; 133662306a36Sopenharmony_ci } 133762306a36Sopenharmony_ci } 133862306a36Sopenharmony_ci} 133962306a36Sopenharmony_ci 134062306a36Sopenharmony_ci/** 134162306a36Sopenharmony_ci * Synchronous work request. Requests work from the POW. 134262306a36Sopenharmony_ci * This function does NOT wait for previous tag switches to complete, 134362306a36Sopenharmony_ci * so the caller must ensure that there is not a pending tag switch. 134462306a36Sopenharmony_ci * 134562306a36Sopenharmony_ci * @wait: When set, call stalls until work becomes avaiable, or times out. 134662306a36Sopenharmony_ci * If not set, returns immediately. 134762306a36Sopenharmony_ci * 134862306a36Sopenharmony_ci * Returns: the WQE pointer from POW. Returns NULL if no work 134962306a36Sopenharmony_ci * was available. 135062306a36Sopenharmony_ci */ 135162306a36Sopenharmony_cistatic inline struct cvmx_wqe *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t 135262306a36Sopenharmony_ci wait) 135362306a36Sopenharmony_ci{ 135462306a36Sopenharmony_ci cvmx_pow_load_addr_t ptr; 135562306a36Sopenharmony_ci cvmx_pow_tag_load_resp_t result; 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 135862306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci ptr.u64 = 0; 136162306a36Sopenharmony_ci ptr.swork.mem_region = CVMX_IO_SEG; 136262306a36Sopenharmony_ci ptr.swork.is_io = 1; 136362306a36Sopenharmony_ci ptr.swork.did = CVMX_OCT_DID_TAG_SWTAG; 136462306a36Sopenharmony_ci ptr.swork.wait = wait; 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci result.u64 = cvmx_read_csr(ptr.u64); 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ci if (result.s_work.no_work) 136962306a36Sopenharmony_ci return NULL; 137062306a36Sopenharmony_ci else 137162306a36Sopenharmony_ci return (struct cvmx_wqe *) cvmx_phys_to_ptr(result.s_work.addr); 137262306a36Sopenharmony_ci} 137362306a36Sopenharmony_ci 137462306a36Sopenharmony_ci/** 137562306a36Sopenharmony_ci * Synchronous work request. Requests work from the POW. 137662306a36Sopenharmony_ci * This function waits for any previous tag switch to complete before 137762306a36Sopenharmony_ci * requesting the new work. 137862306a36Sopenharmony_ci * 137962306a36Sopenharmony_ci * @wait: When set, call stalls until work becomes avaiable, or times out. 138062306a36Sopenharmony_ci * If not set, returns immediately. 138162306a36Sopenharmony_ci * 138262306a36Sopenharmony_ci * Returns: the WQE pointer from POW. Returns NULL if no work 138362306a36Sopenharmony_ci * was available. 138462306a36Sopenharmony_ci */ 138562306a36Sopenharmony_cistatic inline struct cvmx_wqe *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait) 138662306a36Sopenharmony_ci{ 138762306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 138862306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 138962306a36Sopenharmony_ci 139062306a36Sopenharmony_ci /* Must not have a switch pending when requesting work */ 139162306a36Sopenharmony_ci cvmx_pow_tag_sw_wait(); 139262306a36Sopenharmony_ci return cvmx_pow_work_request_sync_nocheck(wait); 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_ci} 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_ci/** 139762306a36Sopenharmony_ci * Synchronous null_rd request. Requests a switch out of NULL_NULL POW state. 139862306a36Sopenharmony_ci * This function waits for any previous tag switch to complete before 139962306a36Sopenharmony_ci * requesting the null_rd. 140062306a36Sopenharmony_ci * 140162306a36Sopenharmony_ci * Returns: the POW state of type cvmx_pow_tag_type_t. 140262306a36Sopenharmony_ci */ 140362306a36Sopenharmony_cistatic inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void) 140462306a36Sopenharmony_ci{ 140562306a36Sopenharmony_ci cvmx_pow_load_addr_t ptr; 140662306a36Sopenharmony_ci cvmx_pow_tag_load_resp_t result; 140762306a36Sopenharmony_ci 140862306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 140962306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci /* Must not have a switch pending when requesting work */ 141262306a36Sopenharmony_ci cvmx_pow_tag_sw_wait(); 141362306a36Sopenharmony_ci 141462306a36Sopenharmony_ci ptr.u64 = 0; 141562306a36Sopenharmony_ci ptr.snull_rd.mem_region = CVMX_IO_SEG; 141662306a36Sopenharmony_ci ptr.snull_rd.is_io = 1; 141762306a36Sopenharmony_ci ptr.snull_rd.did = CVMX_OCT_DID_TAG_NULL_RD; 141862306a36Sopenharmony_ci 141962306a36Sopenharmony_ci result.u64 = cvmx_read_csr(ptr.u64); 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_ci return (enum cvmx_pow_tag_type) result.s_null_rd.state; 142262306a36Sopenharmony_ci} 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci/** 142562306a36Sopenharmony_ci * Asynchronous work request. Work is requested from the POW unit, 142662306a36Sopenharmony_ci * and should later be checked with function 142762306a36Sopenharmony_ci * cvmx_pow_work_response_async. This function does NOT wait for 142862306a36Sopenharmony_ci * previous tag switches to complete, so the caller must ensure that 142962306a36Sopenharmony_ci * there is not a pending tag switch. 143062306a36Sopenharmony_ci * 143162306a36Sopenharmony_ci * @scr_addr: Scratch memory address that response will be returned 143262306a36Sopenharmony_ci * to, which is either a valid WQE, or a response with the 143362306a36Sopenharmony_ci * invalid bit set. Byte address, must be 8 byte aligned. 143462306a36Sopenharmony_ci * 143562306a36Sopenharmony_ci * @wait: 1 to cause response to wait for work to become available (or 143662306a36Sopenharmony_ci * timeout), 0 to cause response to return immediately 143762306a36Sopenharmony_ci */ 143862306a36Sopenharmony_cistatic inline void cvmx_pow_work_request_async_nocheck(int scr_addr, 143962306a36Sopenharmony_ci cvmx_pow_wait_t wait) 144062306a36Sopenharmony_ci{ 144162306a36Sopenharmony_ci cvmx_pow_iobdma_store_t data; 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 144462306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 144562306a36Sopenharmony_ci 144662306a36Sopenharmony_ci /* scr_addr must be 8 byte aligned */ 144762306a36Sopenharmony_ci data.s.scraddr = scr_addr >> 3; 144862306a36Sopenharmony_ci data.s.len = 1; 144962306a36Sopenharmony_ci data.s.did = CVMX_OCT_DID_TAG_SWTAG; 145062306a36Sopenharmony_ci data.s.wait = wait; 145162306a36Sopenharmony_ci cvmx_send_single(data.u64); 145262306a36Sopenharmony_ci} 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_ci/** 145562306a36Sopenharmony_ci * Asynchronous work request. Work is requested from the POW unit, 145662306a36Sopenharmony_ci * and should later be checked with function 145762306a36Sopenharmony_ci * cvmx_pow_work_response_async. This function waits for any previous 145862306a36Sopenharmony_ci * tag switch to complete before requesting the new work. 145962306a36Sopenharmony_ci * 146062306a36Sopenharmony_ci * @scr_addr: Scratch memory address that response will be returned 146162306a36Sopenharmony_ci * to, which is either a valid WQE, or a response with the 146262306a36Sopenharmony_ci * invalid bit set. Byte address, must be 8 byte aligned. 146362306a36Sopenharmony_ci * 146462306a36Sopenharmony_ci * @wait: 1 to cause response to wait for work to become available (or 146562306a36Sopenharmony_ci * timeout), 0 to cause response to return immediately 146662306a36Sopenharmony_ci */ 146762306a36Sopenharmony_cistatic inline void cvmx_pow_work_request_async(int scr_addr, 146862306a36Sopenharmony_ci cvmx_pow_wait_t wait) 146962306a36Sopenharmony_ci{ 147062306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 147162306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 147262306a36Sopenharmony_ci 147362306a36Sopenharmony_ci /* Must not have a switch pending when requesting work */ 147462306a36Sopenharmony_ci cvmx_pow_tag_sw_wait(); 147562306a36Sopenharmony_ci cvmx_pow_work_request_async_nocheck(scr_addr, wait); 147662306a36Sopenharmony_ci} 147762306a36Sopenharmony_ci 147862306a36Sopenharmony_ci/** 147962306a36Sopenharmony_ci * Gets result of asynchronous work request. Performs a IOBDMA sync 148062306a36Sopenharmony_ci * to wait for the response. 148162306a36Sopenharmony_ci * 148262306a36Sopenharmony_ci * @scr_addr: Scratch memory address to get result from Byte address, 148362306a36Sopenharmony_ci * must be 8 byte aligned. 148462306a36Sopenharmony_ci * 148562306a36Sopenharmony_ci * Returns: the WQE from the scratch register, or NULL if no 148662306a36Sopenharmony_ci * work was available. 148762306a36Sopenharmony_ci */ 148862306a36Sopenharmony_cistatic inline struct cvmx_wqe *cvmx_pow_work_response_async(int scr_addr) 148962306a36Sopenharmony_ci{ 149062306a36Sopenharmony_ci cvmx_pow_tag_load_resp_t result; 149162306a36Sopenharmony_ci 149262306a36Sopenharmony_ci CVMX_SYNCIOBDMA; 149362306a36Sopenharmony_ci result.u64 = cvmx_scratch_read64(scr_addr); 149462306a36Sopenharmony_ci 149562306a36Sopenharmony_ci if (result.s_work.no_work) 149662306a36Sopenharmony_ci return NULL; 149762306a36Sopenharmony_ci else 149862306a36Sopenharmony_ci return (struct cvmx_wqe *) cvmx_phys_to_ptr(result.s_work.addr); 149962306a36Sopenharmony_ci} 150062306a36Sopenharmony_ci 150162306a36Sopenharmony_ci/** 150262306a36Sopenharmony_ci * Checks if a work queue entry pointer returned by a work 150362306a36Sopenharmony_ci * request is valid. It may be invalid due to no work 150462306a36Sopenharmony_ci * being available or due to a timeout. 150562306a36Sopenharmony_ci * 150662306a36Sopenharmony_ci * @wqe_ptr: pointer to a work queue entry returned by the POW 150762306a36Sopenharmony_ci * 150862306a36Sopenharmony_ci * Returns 0 if pointer is valid 150962306a36Sopenharmony_ci * 1 if invalid (no work was returned) 151062306a36Sopenharmony_ci */ 151162306a36Sopenharmony_cistatic inline uint64_t cvmx_pow_work_invalid(struct cvmx_wqe *wqe_ptr) 151262306a36Sopenharmony_ci{ 151362306a36Sopenharmony_ci return wqe_ptr == NULL; 151462306a36Sopenharmony_ci} 151562306a36Sopenharmony_ci 151662306a36Sopenharmony_ci/** 151762306a36Sopenharmony_ci * Starts a tag switch to the provided tag value and tag type. 151862306a36Sopenharmony_ci * Completion for the tag switch must be checked for separately. This 151962306a36Sopenharmony_ci * function does NOT update the work queue entry in dram to match tag 152062306a36Sopenharmony_ci * value and type, so the application must keep track of these if they 152162306a36Sopenharmony_ci * are important to the application. This tag switch command must not 152262306a36Sopenharmony_ci * be used for switches to NULL, as the tag switch pending bit will be 152362306a36Sopenharmony_ci * set by the switch request, but never cleared by the hardware. 152462306a36Sopenharmony_ci * 152562306a36Sopenharmony_ci * NOTE: This should not be used when switching from a NULL tag. Use 152662306a36Sopenharmony_ci * cvmx_pow_tag_sw_full() instead. 152762306a36Sopenharmony_ci * 152862306a36Sopenharmony_ci * This function does no checks, so the caller must ensure that any 152962306a36Sopenharmony_ci * previous tag switch has completed. 153062306a36Sopenharmony_ci * 153162306a36Sopenharmony_ci * @tag: new tag value 153262306a36Sopenharmony_ci * @tag_type: new tag type (ordered or atomic) 153362306a36Sopenharmony_ci */ 153462306a36Sopenharmony_cistatic inline void cvmx_pow_tag_sw_nocheck(uint32_t tag, 153562306a36Sopenharmony_ci enum cvmx_pow_tag_type tag_type) 153662306a36Sopenharmony_ci{ 153762306a36Sopenharmony_ci cvmx_addr_t ptr; 153862306a36Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 153962306a36Sopenharmony_ci 154062306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) { 154162306a36Sopenharmony_ci cvmx_pow_tag_req_t current_tag; 154262306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 154362306a36Sopenharmony_ci current_tag = cvmx_pow_get_current_tag(); 154462306a36Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 154562306a36Sopenharmony_ci pr_warn("%s called with NULL_NULL tag\n", __func__); 154662306a36Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 154762306a36Sopenharmony_ci pr_warn("%s called with NULL tag\n", __func__); 154862306a36Sopenharmony_ci if ((current_tag.s.type == tag_type) 154962306a36Sopenharmony_ci && (current_tag.s.tag == tag)) 155062306a36Sopenharmony_ci pr_warn("%s called to perform a tag switch to the same tag\n", 155162306a36Sopenharmony_ci __func__); 155262306a36Sopenharmony_ci if (tag_type == CVMX_POW_TAG_TYPE_NULL) 155362306a36Sopenharmony_ci pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", 155462306a36Sopenharmony_ci __func__); 155562306a36Sopenharmony_ci } 155662306a36Sopenharmony_ci 155762306a36Sopenharmony_ci /* 155862306a36Sopenharmony_ci * Note that WQE in DRAM is not updated here, as the POW does 155962306a36Sopenharmony_ci * not read from DRAM once the WQE is in flight. See hardware 156062306a36Sopenharmony_ci * manual for complete details. It is the application's 156162306a36Sopenharmony_ci * responsibility to keep track of the current tag value if 156262306a36Sopenharmony_ci * that is important. 156362306a36Sopenharmony_ci */ 156462306a36Sopenharmony_ci 156562306a36Sopenharmony_ci tag_req.u64 = 0; 156662306a36Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_SWTAG; 156762306a36Sopenharmony_ci tag_req.s.tag = tag; 156862306a36Sopenharmony_ci tag_req.s.type = tag_type; 156962306a36Sopenharmony_ci 157062306a36Sopenharmony_ci ptr.u64 = 0; 157162306a36Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 157262306a36Sopenharmony_ci ptr.sio.is_io = 1; 157362306a36Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG; 157462306a36Sopenharmony_ci 157562306a36Sopenharmony_ci /* once this store arrives at POW, it will attempt the switch 157662306a36Sopenharmony_ci software must wait for the switch to complete separately */ 157762306a36Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 157862306a36Sopenharmony_ci} 157962306a36Sopenharmony_ci 158062306a36Sopenharmony_ci/** 158162306a36Sopenharmony_ci * Starts a tag switch to the provided tag value and tag type. 158262306a36Sopenharmony_ci * Completion for the tag switch must be checked for separately. This 158362306a36Sopenharmony_ci * function does NOT update the work queue entry in dram to match tag 158462306a36Sopenharmony_ci * value and type, so the application must keep track of these if they 158562306a36Sopenharmony_ci * are important to the application. This tag switch command must not 158662306a36Sopenharmony_ci * be used for switches to NULL, as the tag switch pending bit will be 158762306a36Sopenharmony_ci * set by the switch request, but never cleared by the hardware. 158862306a36Sopenharmony_ci * 158962306a36Sopenharmony_ci * NOTE: This should not be used when switching from a NULL tag. Use 159062306a36Sopenharmony_ci * cvmx_pow_tag_sw_full() instead. 159162306a36Sopenharmony_ci * 159262306a36Sopenharmony_ci * This function waits for any previous tag switch to complete, and also 159362306a36Sopenharmony_ci * displays an error on tag switches to NULL. 159462306a36Sopenharmony_ci * 159562306a36Sopenharmony_ci * @tag: new tag value 159662306a36Sopenharmony_ci * @tag_type: new tag type (ordered or atomic) 159762306a36Sopenharmony_ci */ 159862306a36Sopenharmony_cistatic inline void cvmx_pow_tag_sw(uint32_t tag, 159962306a36Sopenharmony_ci enum cvmx_pow_tag_type tag_type) 160062306a36Sopenharmony_ci{ 160162306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 160262306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 160362306a36Sopenharmony_ci 160462306a36Sopenharmony_ci /* 160562306a36Sopenharmony_ci * Note that WQE in DRAM is not updated here, as the POW does 160662306a36Sopenharmony_ci * not read from DRAM once the WQE is in flight. See hardware 160762306a36Sopenharmony_ci * manual for complete details. It is the application's 160862306a36Sopenharmony_ci * responsibility to keep track of the current tag value if 160962306a36Sopenharmony_ci * that is important. 161062306a36Sopenharmony_ci */ 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_ci /* 161362306a36Sopenharmony_ci * Ensure that there is not a pending tag switch, as a tag 161462306a36Sopenharmony_ci * switch cannot be started if a previous switch is still 161562306a36Sopenharmony_ci * pending. 161662306a36Sopenharmony_ci */ 161762306a36Sopenharmony_ci cvmx_pow_tag_sw_wait(); 161862306a36Sopenharmony_ci cvmx_pow_tag_sw_nocheck(tag, tag_type); 161962306a36Sopenharmony_ci} 162062306a36Sopenharmony_ci 162162306a36Sopenharmony_ci/** 162262306a36Sopenharmony_ci * Starts a tag switch to the provided tag value and tag type. 162362306a36Sopenharmony_ci * Completion for the tag switch must be checked for separately. This 162462306a36Sopenharmony_ci * function does NOT update the work queue entry in dram to match tag 162562306a36Sopenharmony_ci * value and type, so the application must keep track of these if they 162662306a36Sopenharmony_ci * are important to the application. This tag switch command must not 162762306a36Sopenharmony_ci * be used for switches to NULL, as the tag switch pending bit will be 162862306a36Sopenharmony_ci * set by the switch request, but never cleared by the hardware. 162962306a36Sopenharmony_ci * 163062306a36Sopenharmony_ci * This function must be used for tag switches from NULL. 163162306a36Sopenharmony_ci * 163262306a36Sopenharmony_ci * This function does no checks, so the caller must ensure that any 163362306a36Sopenharmony_ci * previous tag switch has completed. 163462306a36Sopenharmony_ci * 163562306a36Sopenharmony_ci * @wqp: pointer to work queue entry to submit. This entry is 163662306a36Sopenharmony_ci * updated to match the other parameters 163762306a36Sopenharmony_ci * @tag: tag value to be assigned to work queue entry 163862306a36Sopenharmony_ci * @tag_type: type of tag 163962306a36Sopenharmony_ci * @group: group value for the work queue entry. 164062306a36Sopenharmony_ci */ 164162306a36Sopenharmony_cistatic inline void cvmx_pow_tag_sw_full_nocheck(struct cvmx_wqe *wqp, uint32_t tag, 164262306a36Sopenharmony_ci enum cvmx_pow_tag_type tag_type, 164362306a36Sopenharmony_ci uint64_t group) 164462306a36Sopenharmony_ci{ 164562306a36Sopenharmony_ci cvmx_addr_t ptr; 164662306a36Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) { 164962306a36Sopenharmony_ci cvmx_pow_tag_req_t current_tag; 165062306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 165162306a36Sopenharmony_ci current_tag = cvmx_pow_get_current_tag(); 165262306a36Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 165362306a36Sopenharmony_ci pr_warn("%s called with NULL_NULL tag\n", __func__); 165462306a36Sopenharmony_ci if ((current_tag.s.type == tag_type) 165562306a36Sopenharmony_ci && (current_tag.s.tag == tag)) 165662306a36Sopenharmony_ci pr_warn("%s called to perform a tag switch to the same tag\n", 165762306a36Sopenharmony_ci __func__); 165862306a36Sopenharmony_ci if (tag_type == CVMX_POW_TAG_TYPE_NULL) 165962306a36Sopenharmony_ci pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", 166062306a36Sopenharmony_ci __func__); 166162306a36Sopenharmony_ci if (wqp != cvmx_phys_to_ptr(0x80)) 166262306a36Sopenharmony_ci if (wqp != cvmx_pow_get_current_wqp()) 166362306a36Sopenharmony_ci pr_warn("%s passed WQE(%p) doesn't match the address in the POW(%p)\n", 166462306a36Sopenharmony_ci __func__, wqp, 166562306a36Sopenharmony_ci cvmx_pow_get_current_wqp()); 166662306a36Sopenharmony_ci } 166762306a36Sopenharmony_ci 166862306a36Sopenharmony_ci /* 166962306a36Sopenharmony_ci * Note that WQE in DRAM is not updated here, as the POW does 167062306a36Sopenharmony_ci * not read from DRAM once the WQE is in flight. See hardware 167162306a36Sopenharmony_ci * manual for complete details. It is the application's 167262306a36Sopenharmony_ci * responsibility to keep track of the current tag value if 167362306a36Sopenharmony_ci * that is important. 167462306a36Sopenharmony_ci */ 167562306a36Sopenharmony_ci 167662306a36Sopenharmony_ci tag_req.u64 = 0; 167762306a36Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_FULL; 167862306a36Sopenharmony_ci tag_req.s.tag = tag; 167962306a36Sopenharmony_ci tag_req.s.type = tag_type; 168062306a36Sopenharmony_ci tag_req.s.grp = group; 168162306a36Sopenharmony_ci 168262306a36Sopenharmony_ci ptr.u64 = 0; 168362306a36Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 168462306a36Sopenharmony_ci ptr.sio.is_io = 1; 168562306a36Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG; 168662306a36Sopenharmony_ci ptr.sio.offset = CAST64(wqp); 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_ci /* 168962306a36Sopenharmony_ci * once this store arrives at POW, it will attempt the switch 169062306a36Sopenharmony_ci * software must wait for the switch to complete separately. 169162306a36Sopenharmony_ci */ 169262306a36Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 169362306a36Sopenharmony_ci} 169462306a36Sopenharmony_ci 169562306a36Sopenharmony_ci/** 169662306a36Sopenharmony_ci * Starts a tag switch to the provided tag value and tag type. 169762306a36Sopenharmony_ci * Completion for the tag switch must be checked for separately. This 169862306a36Sopenharmony_ci * function does NOT update the work queue entry in dram to match tag 169962306a36Sopenharmony_ci * value and type, so the application must keep track of these if they 170062306a36Sopenharmony_ci * are important to the application. This tag switch command must not 170162306a36Sopenharmony_ci * be used for switches to NULL, as the tag switch pending bit will be 170262306a36Sopenharmony_ci * set by the switch request, but never cleared by the hardware. 170362306a36Sopenharmony_ci * 170462306a36Sopenharmony_ci * This function must be used for tag switches from NULL. 170562306a36Sopenharmony_ci * 170662306a36Sopenharmony_ci * This function waits for any pending tag switches to complete 170762306a36Sopenharmony_ci * before requesting the tag switch. 170862306a36Sopenharmony_ci * 170962306a36Sopenharmony_ci * @wqp: pointer to work queue entry to submit. This entry is updated 171062306a36Sopenharmony_ci * to match the other parameters 171162306a36Sopenharmony_ci * @tag: tag value to be assigned to work queue entry 171262306a36Sopenharmony_ci * @tag_type: type of tag 171362306a36Sopenharmony_ci * @group: group value for the work queue entry. 171462306a36Sopenharmony_ci */ 171562306a36Sopenharmony_cistatic inline void cvmx_pow_tag_sw_full(struct cvmx_wqe *wqp, uint32_t tag, 171662306a36Sopenharmony_ci enum cvmx_pow_tag_type tag_type, 171762306a36Sopenharmony_ci uint64_t group) 171862306a36Sopenharmony_ci{ 171962306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 172062306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 172162306a36Sopenharmony_ci 172262306a36Sopenharmony_ci /* 172362306a36Sopenharmony_ci * Ensure that there is not a pending tag switch, as a tag 172462306a36Sopenharmony_ci * switch cannot be started if a previous switch is still 172562306a36Sopenharmony_ci * pending. 172662306a36Sopenharmony_ci */ 172762306a36Sopenharmony_ci cvmx_pow_tag_sw_wait(); 172862306a36Sopenharmony_ci cvmx_pow_tag_sw_full_nocheck(wqp, tag, tag_type, group); 172962306a36Sopenharmony_ci} 173062306a36Sopenharmony_ci 173162306a36Sopenharmony_ci/** 173262306a36Sopenharmony_ci * Switch to a NULL tag, which ends any ordering or 173362306a36Sopenharmony_ci * synchronization provided by the POW for the current 173462306a36Sopenharmony_ci * work queue entry. This operation completes immediately, 173562306a36Sopenharmony_ci * so completion should not be waited for. 173662306a36Sopenharmony_ci * This function does NOT wait for previous tag switches to complete, 173762306a36Sopenharmony_ci * so the caller must ensure that any previous tag switches have completed. 173862306a36Sopenharmony_ci */ 173962306a36Sopenharmony_cistatic inline void cvmx_pow_tag_sw_null_nocheck(void) 174062306a36Sopenharmony_ci{ 174162306a36Sopenharmony_ci cvmx_addr_t ptr; 174262306a36Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 174362306a36Sopenharmony_ci 174462306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) { 174562306a36Sopenharmony_ci cvmx_pow_tag_req_t current_tag; 174662306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 174762306a36Sopenharmony_ci current_tag = cvmx_pow_get_current_tag(); 174862306a36Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 174962306a36Sopenharmony_ci pr_warn("%s called with NULL_NULL tag\n", __func__); 175062306a36Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 175162306a36Sopenharmony_ci pr_warn("%s called when we already have a NULL tag\n", 175262306a36Sopenharmony_ci __func__); 175362306a36Sopenharmony_ci } 175462306a36Sopenharmony_ci 175562306a36Sopenharmony_ci tag_req.u64 = 0; 175662306a36Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_SWTAG; 175762306a36Sopenharmony_ci tag_req.s.type = CVMX_POW_TAG_TYPE_NULL; 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_ci ptr.u64 = 0; 176062306a36Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 176162306a36Sopenharmony_ci ptr.sio.is_io = 1; 176262306a36Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_TAG1; 176362306a36Sopenharmony_ci 176462306a36Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 176562306a36Sopenharmony_ci 176662306a36Sopenharmony_ci /* switch to NULL completes immediately */ 176762306a36Sopenharmony_ci} 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci/** 177062306a36Sopenharmony_ci * Switch to a NULL tag, which ends any ordering or 177162306a36Sopenharmony_ci * synchronization provided by the POW for the current 177262306a36Sopenharmony_ci * work queue entry. This operation completes immediately, 177362306a36Sopenharmony_ci * so completion should not be waited for. 177462306a36Sopenharmony_ci * This function waits for any pending tag switches to complete 177562306a36Sopenharmony_ci * before requesting the switch to NULL. 177662306a36Sopenharmony_ci */ 177762306a36Sopenharmony_cistatic inline void cvmx_pow_tag_sw_null(void) 177862306a36Sopenharmony_ci{ 177962306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 178062306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 178162306a36Sopenharmony_ci 178262306a36Sopenharmony_ci /* 178362306a36Sopenharmony_ci * Ensure that there is not a pending tag switch, as a tag 178462306a36Sopenharmony_ci * switch cannot be started if a previous switch is still 178562306a36Sopenharmony_ci * pending. 178662306a36Sopenharmony_ci */ 178762306a36Sopenharmony_ci cvmx_pow_tag_sw_wait(); 178862306a36Sopenharmony_ci cvmx_pow_tag_sw_null_nocheck(); 178962306a36Sopenharmony_ci 179062306a36Sopenharmony_ci /* switch to NULL completes immediately */ 179162306a36Sopenharmony_ci} 179262306a36Sopenharmony_ci 179362306a36Sopenharmony_ci/** 179462306a36Sopenharmony_ci * Submits work to an input queue. This function updates the work 179562306a36Sopenharmony_ci * queue entry in DRAM to match the arguments given. Note that the 179662306a36Sopenharmony_ci * tag provided is for the work queue entry submitted, and is 179762306a36Sopenharmony_ci * unrelated to the tag that the core currently holds. 179862306a36Sopenharmony_ci * 179962306a36Sopenharmony_ci * @wqp: pointer to work queue entry to submit. This entry is 180062306a36Sopenharmony_ci * updated to match the other parameters 180162306a36Sopenharmony_ci * @tag: tag value to be assigned to work queue entry 180262306a36Sopenharmony_ci * @tag_type: type of tag 180362306a36Sopenharmony_ci * @qos: Input queue to add to. 180462306a36Sopenharmony_ci * @grp: group value for the work queue entry. 180562306a36Sopenharmony_ci */ 180662306a36Sopenharmony_cistatic inline void cvmx_pow_work_submit(struct cvmx_wqe *wqp, uint32_t tag, 180762306a36Sopenharmony_ci enum cvmx_pow_tag_type tag_type, 180862306a36Sopenharmony_ci uint64_t qos, uint64_t grp) 180962306a36Sopenharmony_ci{ 181062306a36Sopenharmony_ci cvmx_addr_t ptr; 181162306a36Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 181262306a36Sopenharmony_ci 181362306a36Sopenharmony_ci wqp->word1.tag = tag; 181462306a36Sopenharmony_ci wqp->word1.tag_type = tag_type; 181562306a36Sopenharmony_ci 181662306a36Sopenharmony_ci cvmx_wqe_set_qos(wqp, qos); 181762306a36Sopenharmony_ci cvmx_wqe_set_grp(wqp, grp); 181862306a36Sopenharmony_ci 181962306a36Sopenharmony_ci tag_req.u64 = 0; 182062306a36Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ; 182162306a36Sopenharmony_ci tag_req.s.type = tag_type; 182262306a36Sopenharmony_ci tag_req.s.tag = tag; 182362306a36Sopenharmony_ci tag_req.s.qos = qos; 182462306a36Sopenharmony_ci tag_req.s.grp = grp; 182562306a36Sopenharmony_ci 182662306a36Sopenharmony_ci ptr.u64 = 0; 182762306a36Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 182862306a36Sopenharmony_ci ptr.sio.is_io = 1; 182962306a36Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_TAG1; 183062306a36Sopenharmony_ci ptr.sio.offset = cvmx_ptr_to_phys(wqp); 183162306a36Sopenharmony_ci 183262306a36Sopenharmony_ci /* 183362306a36Sopenharmony_ci * SYNC write to memory before the work submit. This is 183462306a36Sopenharmony_ci * necessary as POW may read values from DRAM at this time. 183562306a36Sopenharmony_ci */ 183662306a36Sopenharmony_ci CVMX_SYNCWS; 183762306a36Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 183862306a36Sopenharmony_ci} 183962306a36Sopenharmony_ci 184062306a36Sopenharmony_ci/** 184162306a36Sopenharmony_ci * This function sets the group mask for a core. The group mask 184262306a36Sopenharmony_ci * indicates which groups each core will accept work from. There are 184362306a36Sopenharmony_ci * 16 groups. 184462306a36Sopenharmony_ci * 184562306a36Sopenharmony_ci * @core_num: core to apply mask to 184662306a36Sopenharmony_ci * @mask: Group mask. There are 16 groups, so only bits 0-15 are valid, 184762306a36Sopenharmony_ci * representing groups 0-15. 184862306a36Sopenharmony_ci * Each 1 bit in the mask enables the core to accept work from 184962306a36Sopenharmony_ci * the corresponding group. 185062306a36Sopenharmony_ci */ 185162306a36Sopenharmony_cistatic inline void cvmx_pow_set_group_mask(uint64_t core_num, uint64_t mask) 185262306a36Sopenharmony_ci{ 185362306a36Sopenharmony_ci union cvmx_pow_pp_grp_mskx grp_msk; 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ci grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num)); 185662306a36Sopenharmony_ci grp_msk.s.grp_msk = mask; 185762306a36Sopenharmony_ci cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64); 185862306a36Sopenharmony_ci} 185962306a36Sopenharmony_ci 186062306a36Sopenharmony_ci/** 186162306a36Sopenharmony_ci * This function sets POW static priorities for a core. Each input queue has 186262306a36Sopenharmony_ci * an associated priority value. 186362306a36Sopenharmony_ci * 186462306a36Sopenharmony_ci * @core_num: core to apply priorities to 186562306a36Sopenharmony_ci * @priority: Vector of 8 priorities, one per POW Input Queue (0-7). 186662306a36Sopenharmony_ci * Highest priority is 0 and lowest is 7. A priority value 186762306a36Sopenharmony_ci * of 0xF instructs POW to skip the Input Queue when 186862306a36Sopenharmony_ci * scheduling to this specific core. 186962306a36Sopenharmony_ci * NOTE: priorities should not have gaps in values, meaning 187062306a36Sopenharmony_ci * {0,1,1,1,1,1,1,1} is a valid configuration while 187162306a36Sopenharmony_ci * {0,2,2,2,2,2,2,2} is not. 187262306a36Sopenharmony_ci */ 187362306a36Sopenharmony_cistatic inline void cvmx_pow_set_priority(uint64_t core_num, 187462306a36Sopenharmony_ci const uint8_t priority[]) 187562306a36Sopenharmony_ci{ 187662306a36Sopenharmony_ci /* POW priorities are supported on CN5xxx and later */ 187762306a36Sopenharmony_ci if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) { 187862306a36Sopenharmony_ci union cvmx_pow_pp_grp_mskx grp_msk; 187962306a36Sopenharmony_ci 188062306a36Sopenharmony_ci grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num)); 188162306a36Sopenharmony_ci grp_msk.s.qos0_pri = priority[0]; 188262306a36Sopenharmony_ci grp_msk.s.qos1_pri = priority[1]; 188362306a36Sopenharmony_ci grp_msk.s.qos2_pri = priority[2]; 188462306a36Sopenharmony_ci grp_msk.s.qos3_pri = priority[3]; 188562306a36Sopenharmony_ci grp_msk.s.qos4_pri = priority[4]; 188662306a36Sopenharmony_ci grp_msk.s.qos5_pri = priority[5]; 188762306a36Sopenharmony_ci grp_msk.s.qos6_pri = priority[6]; 188862306a36Sopenharmony_ci grp_msk.s.qos7_pri = priority[7]; 188962306a36Sopenharmony_ci 189062306a36Sopenharmony_ci /* Detect gaps between priorities and flag error */ 189162306a36Sopenharmony_ci { 189262306a36Sopenharmony_ci int i; 189362306a36Sopenharmony_ci uint32_t prio_mask = 0; 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_ci for (i = 0; i < 8; i++) 189662306a36Sopenharmony_ci if (priority[i] != 0xF) 189762306a36Sopenharmony_ci prio_mask |= 1 << priority[i]; 189862306a36Sopenharmony_ci 189962306a36Sopenharmony_ci if (prio_mask ^ ((1 << cvmx_pop(prio_mask)) - 1)) { 190062306a36Sopenharmony_ci pr_err("POW static priorities should be " 190162306a36Sopenharmony_ci "contiguous (0x%llx)\n", 190262306a36Sopenharmony_ci (unsigned long long)prio_mask); 190362306a36Sopenharmony_ci return; 190462306a36Sopenharmony_ci } 190562306a36Sopenharmony_ci } 190662306a36Sopenharmony_ci 190762306a36Sopenharmony_ci cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64); 190862306a36Sopenharmony_ci } 190962306a36Sopenharmony_ci} 191062306a36Sopenharmony_ci 191162306a36Sopenharmony_ci/** 191262306a36Sopenharmony_ci * Performs a tag switch and then an immediate deschedule. This completes 191362306a36Sopenharmony_ci * immediately, so completion must not be waited for. This function does NOT 191462306a36Sopenharmony_ci * update the wqe in DRAM to match arguments. 191562306a36Sopenharmony_ci * 191662306a36Sopenharmony_ci * This function does NOT wait for any prior tag switches to complete, so the 191762306a36Sopenharmony_ci * calling code must do this. 191862306a36Sopenharmony_ci * 191962306a36Sopenharmony_ci * Note the following CAVEAT of the Octeon HW behavior when 192062306a36Sopenharmony_ci * re-scheduling DE-SCHEDULEd items whose (next) state is 192162306a36Sopenharmony_ci * ORDERED: 192262306a36Sopenharmony_ci * - If there are no switches pending at the time that the 192362306a36Sopenharmony_ci * HW executes the de-schedule, the HW will only re-schedule 192462306a36Sopenharmony_ci * the head of the FIFO associated with the given tag. This 192562306a36Sopenharmony_ci * means that in many respects, the HW treats this ORDERED 192662306a36Sopenharmony_ci * tag as an ATOMIC tag. Note that in the SWTAG_DESCH 192762306a36Sopenharmony_ci * case (to an ORDERED tag), the HW will do the switch 192862306a36Sopenharmony_ci * before the deschedule whenever it is possible to do 192962306a36Sopenharmony_ci * the switch immediately, so it may often look like 193062306a36Sopenharmony_ci * this case. 193162306a36Sopenharmony_ci * - If there is a pending switch to ORDERED at the time 193262306a36Sopenharmony_ci * the HW executes the de-schedule, the HW will perform 193362306a36Sopenharmony_ci * the switch at the time it re-schedules, and will be 193462306a36Sopenharmony_ci * able to reschedule any/all of the entries with the 193562306a36Sopenharmony_ci * same tag. 193662306a36Sopenharmony_ci * Due to this behavior, the RECOMMENDATION to software is 193762306a36Sopenharmony_ci * that they have a (next) state of ATOMIC when they 193862306a36Sopenharmony_ci * DE-SCHEDULE. If an ORDERED tag is what was really desired, 193962306a36Sopenharmony_ci * SW can choose to immediately switch to an ORDERED tag 194062306a36Sopenharmony_ci * after the work (that has an ATOMIC tag) is re-scheduled. 194162306a36Sopenharmony_ci * Note that since there are never any tag switches pending 194262306a36Sopenharmony_ci * when the HW re-schedules, this switch can be IMMEDIATE upon 194362306a36Sopenharmony_ci * the reception of the pointer during the re-schedule. 194462306a36Sopenharmony_ci * 194562306a36Sopenharmony_ci * @tag: New tag value 194662306a36Sopenharmony_ci * @tag_type: New tag type 194762306a36Sopenharmony_ci * @group: New group value 194862306a36Sopenharmony_ci * @no_sched: Control whether this work queue entry will be rescheduled. 194962306a36Sopenharmony_ci * - 1 : don't schedule this work 195062306a36Sopenharmony_ci * - 0 : allow this work to be scheduled. 195162306a36Sopenharmony_ci */ 195262306a36Sopenharmony_cistatic inline void cvmx_pow_tag_sw_desched_nocheck( 195362306a36Sopenharmony_ci uint32_t tag, 195462306a36Sopenharmony_ci enum cvmx_pow_tag_type tag_type, 195562306a36Sopenharmony_ci uint64_t group, 195662306a36Sopenharmony_ci uint64_t no_sched) 195762306a36Sopenharmony_ci{ 195862306a36Sopenharmony_ci cvmx_addr_t ptr; 195962306a36Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 196062306a36Sopenharmony_ci 196162306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) { 196262306a36Sopenharmony_ci cvmx_pow_tag_req_t current_tag; 196362306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 196462306a36Sopenharmony_ci current_tag = cvmx_pow_get_current_tag(); 196562306a36Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 196662306a36Sopenharmony_ci pr_warn("%s called with NULL_NULL tag\n", __func__); 196762306a36Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 196862306a36Sopenharmony_ci pr_warn("%s called with NULL tag. Deschedule not allowed from NULL state\n", 196962306a36Sopenharmony_ci __func__); 197062306a36Sopenharmony_ci if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) 197162306a36Sopenharmony_ci && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) 197262306a36Sopenharmony_ci pr_warn("%s called where neither the before or after tag is ATOMIC\n", 197362306a36Sopenharmony_ci __func__); 197462306a36Sopenharmony_ci } 197562306a36Sopenharmony_ci 197662306a36Sopenharmony_ci tag_req.u64 = 0; 197762306a36Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_DESCH; 197862306a36Sopenharmony_ci tag_req.s.tag = tag; 197962306a36Sopenharmony_ci tag_req.s.type = tag_type; 198062306a36Sopenharmony_ci tag_req.s.grp = group; 198162306a36Sopenharmony_ci tag_req.s.no_sched = no_sched; 198262306a36Sopenharmony_ci 198362306a36Sopenharmony_ci ptr.u64 = 0; 198462306a36Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 198562306a36Sopenharmony_ci ptr.sio.is_io = 1; 198662306a36Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_TAG3; 198762306a36Sopenharmony_ci /* 198862306a36Sopenharmony_ci * since TAG3 is used, this store will clear the local pending 198962306a36Sopenharmony_ci * switch bit. 199062306a36Sopenharmony_ci */ 199162306a36Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 199262306a36Sopenharmony_ci} 199362306a36Sopenharmony_ci 199462306a36Sopenharmony_ci/** 199562306a36Sopenharmony_ci * Performs a tag switch and then an immediate deschedule. This completes 199662306a36Sopenharmony_ci * immediately, so completion must not be waited for. This function does NOT 199762306a36Sopenharmony_ci * update the wqe in DRAM to match arguments. 199862306a36Sopenharmony_ci * 199962306a36Sopenharmony_ci * This function waits for any prior tag switches to complete, so the 200062306a36Sopenharmony_ci * calling code may call this function with a pending tag switch. 200162306a36Sopenharmony_ci * 200262306a36Sopenharmony_ci * Note the following CAVEAT of the Octeon HW behavior when 200362306a36Sopenharmony_ci * re-scheduling DE-SCHEDULEd items whose (next) state is 200462306a36Sopenharmony_ci * ORDERED: 200562306a36Sopenharmony_ci * - If there are no switches pending at the time that the 200662306a36Sopenharmony_ci * HW executes the de-schedule, the HW will only re-schedule 200762306a36Sopenharmony_ci * the head of the FIFO associated with the given tag. This 200862306a36Sopenharmony_ci * means that in many respects, the HW treats this ORDERED 200962306a36Sopenharmony_ci * tag as an ATOMIC tag. Note that in the SWTAG_DESCH 201062306a36Sopenharmony_ci * case (to an ORDERED tag), the HW will do the switch 201162306a36Sopenharmony_ci * before the deschedule whenever it is possible to do 201262306a36Sopenharmony_ci * the switch immediately, so it may often look like 201362306a36Sopenharmony_ci * this case. 201462306a36Sopenharmony_ci * - If there is a pending switch to ORDERED at the time 201562306a36Sopenharmony_ci * the HW executes the de-schedule, the HW will perform 201662306a36Sopenharmony_ci * the switch at the time it re-schedules, and will be 201762306a36Sopenharmony_ci * able to reschedule any/all of the entries with the 201862306a36Sopenharmony_ci * same tag. 201962306a36Sopenharmony_ci * Due to this behavior, the RECOMMENDATION to software is 202062306a36Sopenharmony_ci * that they have a (next) state of ATOMIC when they 202162306a36Sopenharmony_ci * DE-SCHEDULE. If an ORDERED tag is what was really desired, 202262306a36Sopenharmony_ci * SW can choose to immediately switch to an ORDERED tag 202362306a36Sopenharmony_ci * after the work (that has an ATOMIC tag) is re-scheduled. 202462306a36Sopenharmony_ci * Note that since there are never any tag switches pending 202562306a36Sopenharmony_ci * when the HW re-schedules, this switch can be IMMEDIATE upon 202662306a36Sopenharmony_ci * the reception of the pointer during the re-schedule. 202762306a36Sopenharmony_ci * 202862306a36Sopenharmony_ci * @tag: New tag value 202962306a36Sopenharmony_ci * @tag_type: New tag type 203062306a36Sopenharmony_ci * @group: New group value 203162306a36Sopenharmony_ci * @no_sched: Control whether this work queue entry will be rescheduled. 203262306a36Sopenharmony_ci * - 1 : don't schedule this work 203362306a36Sopenharmony_ci * - 0 : allow this work to be scheduled. 203462306a36Sopenharmony_ci */ 203562306a36Sopenharmony_cistatic inline void cvmx_pow_tag_sw_desched(uint32_t tag, 203662306a36Sopenharmony_ci enum cvmx_pow_tag_type tag_type, 203762306a36Sopenharmony_ci uint64_t group, uint64_t no_sched) 203862306a36Sopenharmony_ci{ 203962306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) 204062306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 204162306a36Sopenharmony_ci 204262306a36Sopenharmony_ci /* Need to make sure any writes to the work queue entry are complete */ 204362306a36Sopenharmony_ci CVMX_SYNCWS; 204462306a36Sopenharmony_ci /* 204562306a36Sopenharmony_ci * Ensure that there is not a pending tag switch, as a tag 204662306a36Sopenharmony_ci * switch cannot be started if a previous switch is still 204762306a36Sopenharmony_ci * pending. 204862306a36Sopenharmony_ci */ 204962306a36Sopenharmony_ci cvmx_pow_tag_sw_wait(); 205062306a36Sopenharmony_ci cvmx_pow_tag_sw_desched_nocheck(tag, tag_type, group, no_sched); 205162306a36Sopenharmony_ci} 205262306a36Sopenharmony_ci 205362306a36Sopenharmony_ci/** 205462306a36Sopenharmony_ci * Deschedules the current work queue entry. 205562306a36Sopenharmony_ci * 205662306a36Sopenharmony_ci * @no_sched: no schedule flag value to be set on the work queue 205762306a36Sopenharmony_ci * entry. If this is set the entry will not be 205862306a36Sopenharmony_ci * rescheduled. 205962306a36Sopenharmony_ci */ 206062306a36Sopenharmony_cistatic inline void cvmx_pow_desched(uint64_t no_sched) 206162306a36Sopenharmony_ci{ 206262306a36Sopenharmony_ci cvmx_addr_t ptr; 206362306a36Sopenharmony_ci cvmx_pow_tag_req_t tag_req; 206462306a36Sopenharmony_ci 206562306a36Sopenharmony_ci if (CVMX_ENABLE_POW_CHECKS) { 206662306a36Sopenharmony_ci cvmx_pow_tag_req_t current_tag; 206762306a36Sopenharmony_ci __cvmx_pow_warn_if_pending_switch(__func__); 206862306a36Sopenharmony_ci current_tag = cvmx_pow_get_current_tag(); 206962306a36Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 207062306a36Sopenharmony_ci pr_warn("%s called with NULL_NULL tag\n", __func__); 207162306a36Sopenharmony_ci if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 207262306a36Sopenharmony_ci pr_warn("%s called with NULL tag. Deschedule not expected from NULL state\n", 207362306a36Sopenharmony_ci __func__); 207462306a36Sopenharmony_ci } 207562306a36Sopenharmony_ci 207662306a36Sopenharmony_ci /* Need to make sure any writes to the work queue entry are complete */ 207762306a36Sopenharmony_ci CVMX_SYNCWS; 207862306a36Sopenharmony_ci 207962306a36Sopenharmony_ci tag_req.u64 = 0; 208062306a36Sopenharmony_ci tag_req.s.op = CVMX_POW_TAG_OP_DESCH; 208162306a36Sopenharmony_ci tag_req.s.no_sched = no_sched; 208262306a36Sopenharmony_ci 208362306a36Sopenharmony_ci ptr.u64 = 0; 208462306a36Sopenharmony_ci ptr.sio.mem_region = CVMX_IO_SEG; 208562306a36Sopenharmony_ci ptr.sio.is_io = 1; 208662306a36Sopenharmony_ci ptr.sio.did = CVMX_OCT_DID_TAG_TAG3; 208762306a36Sopenharmony_ci /* 208862306a36Sopenharmony_ci * since TAG3 is used, this store will clear the local pending 208962306a36Sopenharmony_ci * switch bit. 209062306a36Sopenharmony_ci */ 209162306a36Sopenharmony_ci cvmx_write_io(ptr.u64, tag_req.u64); 209262306a36Sopenharmony_ci} 209362306a36Sopenharmony_ci 209462306a36Sopenharmony_ci/**************************************************** 209562306a36Sopenharmony_ci* Define usage of bits within the 32 bit tag values. 209662306a36Sopenharmony_ci*****************************************************/ 209762306a36Sopenharmony_ci 209862306a36Sopenharmony_ci/* 209962306a36Sopenharmony_ci * Number of bits of the tag used by software. The SW bits are always 210062306a36Sopenharmony_ci * a contiguous block of the high starting at bit 31. The hardware 210162306a36Sopenharmony_ci * bits are always the low bits. By default, the top 8 bits of the 210262306a36Sopenharmony_ci * tag are reserved for software, and the low 24 are set by the IPD 210362306a36Sopenharmony_ci * unit. 210462306a36Sopenharmony_ci */ 210562306a36Sopenharmony_ci#define CVMX_TAG_SW_BITS (8) 210662306a36Sopenharmony_ci#define CVMX_TAG_SW_SHIFT (32 - CVMX_TAG_SW_BITS) 210762306a36Sopenharmony_ci 210862306a36Sopenharmony_ci/* Below is the list of values for the top 8 bits of the tag. */ 210962306a36Sopenharmony_ci/* 211062306a36Sopenharmony_ci * Tag values with top byte of this value are reserved for internal 211162306a36Sopenharmony_ci * executive uses. 211262306a36Sopenharmony_ci */ 211362306a36Sopenharmony_ci#define CVMX_TAG_SW_BITS_INTERNAL 0x1 211462306a36Sopenharmony_ci/* The executive divides the remaining 24 bits as follows: 211562306a36Sopenharmony_ci * - the upper 8 bits (bits 23 - 16 of the tag) define a subgroup 211662306a36Sopenharmony_ci * 211762306a36Sopenharmony_ci * - the lower 16 bits (bits 15 - 0 of the tag) define are the value 211862306a36Sopenharmony_ci * with the subgroup 211962306a36Sopenharmony_ci * 212062306a36Sopenharmony_ci * Note that this section describes the format of tags generated by 212162306a36Sopenharmony_ci * software - refer to the hardware documentation for a description of 212262306a36Sopenharmony_ci * the tags values generated by the packet input hardware. Subgroups 212362306a36Sopenharmony_ci * are defined here. 212462306a36Sopenharmony_ci */ 212562306a36Sopenharmony_ci/* Mask for the value portion of the tag */ 212662306a36Sopenharmony_ci#define CVMX_TAG_SUBGROUP_MASK 0xFFFF 212762306a36Sopenharmony_ci#define CVMX_TAG_SUBGROUP_SHIFT 16 212862306a36Sopenharmony_ci#define CVMX_TAG_SUBGROUP_PKO 0x1 212962306a36Sopenharmony_ci 213062306a36Sopenharmony_ci/* End of executive tag subgroup definitions */ 213162306a36Sopenharmony_ci 213262306a36Sopenharmony_ci/* 213362306a36Sopenharmony_ci * The remaining values software bit values 0x2 - 0xff are available 213462306a36Sopenharmony_ci * for application use. 213562306a36Sopenharmony_ci */ 213662306a36Sopenharmony_ci 213762306a36Sopenharmony_ci/** 213862306a36Sopenharmony_ci * This function creates a 32 bit tag value from the two values provided. 213962306a36Sopenharmony_ci * 214062306a36Sopenharmony_ci * @sw_bits: The upper bits (number depends on configuration) are set 214162306a36Sopenharmony_ci * to this value. The remainder of bits are set by the 214262306a36Sopenharmony_ci * hw_bits parameter. 214362306a36Sopenharmony_ci * 214462306a36Sopenharmony_ci * @hw_bits: The lower bits (number depends on configuration) are set 214562306a36Sopenharmony_ci * to this value. The remainder of bits are set by the 214662306a36Sopenharmony_ci * sw_bits parameter. 214762306a36Sopenharmony_ci * 214862306a36Sopenharmony_ci * Returns 32 bit value of the combined hw and sw bits. 214962306a36Sopenharmony_ci */ 215062306a36Sopenharmony_cistatic inline uint32_t cvmx_pow_tag_compose(uint64_t sw_bits, uint64_t hw_bits) 215162306a36Sopenharmony_ci{ 215262306a36Sopenharmony_ci return ((sw_bits & cvmx_build_mask(CVMX_TAG_SW_BITS)) << 215362306a36Sopenharmony_ci CVMX_TAG_SW_SHIFT) | 215462306a36Sopenharmony_ci (hw_bits & cvmx_build_mask(32 - CVMX_TAG_SW_BITS)); 215562306a36Sopenharmony_ci} 215662306a36Sopenharmony_ci 215762306a36Sopenharmony_ci/** 215862306a36Sopenharmony_ci * Extracts the bits allocated for software use from the tag 215962306a36Sopenharmony_ci * 216062306a36Sopenharmony_ci * @tag: 32 bit tag value 216162306a36Sopenharmony_ci * 216262306a36Sopenharmony_ci * Returns N bit software tag value, where N is configurable with the 216362306a36Sopenharmony_ci * CVMX_TAG_SW_BITS define 216462306a36Sopenharmony_ci */ 216562306a36Sopenharmony_cistatic inline uint32_t cvmx_pow_tag_get_sw_bits(uint64_t tag) 216662306a36Sopenharmony_ci{ 216762306a36Sopenharmony_ci return (tag >> (32 - CVMX_TAG_SW_BITS)) & 216862306a36Sopenharmony_ci cvmx_build_mask(CVMX_TAG_SW_BITS); 216962306a36Sopenharmony_ci} 217062306a36Sopenharmony_ci 217162306a36Sopenharmony_ci/** 217262306a36Sopenharmony_ci * 217362306a36Sopenharmony_ci * Extracts the bits allocated for hardware use from the tag 217462306a36Sopenharmony_ci * 217562306a36Sopenharmony_ci * @tag: 32 bit tag value 217662306a36Sopenharmony_ci * 217762306a36Sopenharmony_ci * Returns (32 - N) bit software tag value, where N is configurable 217862306a36Sopenharmony_ci * with the CVMX_TAG_SW_BITS define 217962306a36Sopenharmony_ci */ 218062306a36Sopenharmony_cistatic inline uint32_t cvmx_pow_tag_get_hw_bits(uint64_t tag) 218162306a36Sopenharmony_ci{ 218262306a36Sopenharmony_ci return tag & cvmx_build_mask(32 - CVMX_TAG_SW_BITS); 218362306a36Sopenharmony_ci} 218462306a36Sopenharmony_ci 218562306a36Sopenharmony_ci/** 218662306a36Sopenharmony_ci * Store the current POW internal state into the supplied 218762306a36Sopenharmony_ci * buffer. It is recommended that you pass a buffer of at least 218862306a36Sopenharmony_ci * 128KB. The format of the capture may change based on SDK 218962306a36Sopenharmony_ci * version and Octeon chip. 219062306a36Sopenharmony_ci * 219162306a36Sopenharmony_ci * @buffer: Buffer to store capture into 219262306a36Sopenharmony_ci * @buffer_size: 219362306a36Sopenharmony_ci * The size of the supplied buffer 219462306a36Sopenharmony_ci * 219562306a36Sopenharmony_ci * Returns Zero on success, negative on failure 219662306a36Sopenharmony_ci */ 219762306a36Sopenharmony_ciextern int cvmx_pow_capture(void *buffer, int buffer_size); 219862306a36Sopenharmony_ci 219962306a36Sopenharmony_ci/** 220062306a36Sopenharmony_ci * Dump a POW capture to the console in a human readable format. 220162306a36Sopenharmony_ci * 220262306a36Sopenharmony_ci * @buffer: POW capture from cvmx_pow_capture() 220362306a36Sopenharmony_ci * @buffer_size: 220462306a36Sopenharmony_ci * Size of the buffer 220562306a36Sopenharmony_ci */ 220662306a36Sopenharmony_ciextern void cvmx_pow_display(void *buffer, int buffer_size); 220762306a36Sopenharmony_ci 220862306a36Sopenharmony_ci/** 220962306a36Sopenharmony_ci * Return the number of POW entries supported by this chip 221062306a36Sopenharmony_ci * 221162306a36Sopenharmony_ci * Returns Number of POW entries 221262306a36Sopenharmony_ci */ 221362306a36Sopenharmony_ciextern int cvmx_pow_get_num_entries(void); 221462306a36Sopenharmony_ci 221562306a36Sopenharmony_ci#endif /* __CVMX_POW_H__ */ 2216