cvmx-pow.h 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983
  1. /***********************license start***************
  2. * Author: Cavium Networks
  3. *
  4. * Contact: support@caviumnetworks.com
  5. * This file is part of the OCTEON SDK
  6. *
  7. * Copyright (c) 2003-2008 Cavium Networks
  8. *
  9. * This file is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License, Version 2, as
  11. * published by the Free Software Foundation.
  12. *
  13. * This file is distributed in the hope that it will be useful, but
  14. * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
  15. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
  16. * NONINFRINGEMENT. See the GNU General Public License for more
  17. * details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this file; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22. * or visit http://www.gnu.org/licenses/.
  23. *
  24. * This file may also be available under a different license from Cavium.
  25. * Contact Cavium Networks for more information
  26. ***********************license end**************************************/
  27. /**
  28. * Interface to the hardware Packet Order / Work unit.
  29. *
  30. * New, starting with SDK 1.7.0, cvmx-pow supports a number of
  31. * extended consistency checks. The define
  32. * CVMX_ENABLE_POW_CHECKS controls the runtime insertion of POW
  33. * internal state checks to find common programming errors. If
  34. * CVMX_ENABLE_POW_CHECKS is not defined, checks are by default
  35. * enabled. For example, cvmx-pow will check for the following
  36. * program errors or POW state inconsistency.
  37. * - Requesting a POW operation with an active tag switch in
  38. * progress.
  39. * - Waiting for a tag switch to complete for an excessively
  40. * long period. This is normally a sign of an error in locking
  41. * causing deadlock.
  42. * - Illegal tag switches from NULL_NULL.
  43. * - Illegal tag switches from NULL.
  44. * - Illegal deschedule request.
  45. * - WQE pointer not matching the one attached to the core by
  46. * the POW.
  47. *
  48. */
  49. #ifndef __CVMX_POW_H__
  50. #define __CVMX_POW_H__
  51. #include <asm/octeon/cvmx-pow-defs.h>
  52. #include "cvmx-scratch.h"
  53. #include "cvmx-wqe.h"
  54. /* Default to having all POW constancy checks turned on */
  55. #ifndef CVMX_ENABLE_POW_CHECKS
  56. #define CVMX_ENABLE_POW_CHECKS 1
  57. #endif
  58. enum cvmx_pow_tag_type {
  59. /* Tag ordering is maintained */
  60. CVMX_POW_TAG_TYPE_ORDERED = 0L,
  61. /* Tag ordering is maintained, and at most one PP has the tag */
  62. CVMX_POW_TAG_TYPE_ATOMIC = 1L,
  63. /*
  64. * The work queue entry from the order - NEVER tag switch from
  65. * NULL to NULL
  66. */
  67. CVMX_POW_TAG_TYPE_NULL = 2L,
  68. /* A tag switch to NULL, and there is no space reserved in POW
  69. * - NEVER tag switch to NULL_NULL
  70. * - NEVER tag switch from NULL_NULL
  71. * - NULL_NULL is entered at the beginning of time and on a deschedule.
  72. * - NULL_NULL can be exited by a new work request. A NULL_SWITCH
  73. * load can also switch the state to NULL
  74. */
  75. CVMX_POW_TAG_TYPE_NULL_NULL = 3L
  76. };
  77. /**
  78. * Wait flag values for pow functions.
  79. */
  80. typedef enum {
  81. CVMX_POW_WAIT = 1,
  82. CVMX_POW_NO_WAIT = 0,
  83. } cvmx_pow_wait_t;
  84. /**
  85. * POW tag operations. These are used in the data stored to the POW.
  86. */
  87. typedef enum {
  88. /*
  89. * switch the tag (only) for this PP
  90. * - the previous tag should be non-NULL in this case
  91. * - tag switch response required
  92. * - fields used: op, type, tag
  93. */
  94. CVMX_POW_TAG_OP_SWTAG = 0L,
  95. /*
  96. * switch the tag for this PP, with full information
  97. * - this should be used when the previous tag is NULL
  98. * - tag switch response required
  99. * - fields used: address, op, grp, type, tag
  100. */
  101. CVMX_POW_TAG_OP_SWTAG_FULL = 1L,
  102. /*
  103. * switch the tag (and/or group) for this PP and de-schedule
  104. * - OK to keep the tag the same and only change the group
  105. * - fields used: op, no_sched, grp, type, tag
  106. */
  107. CVMX_POW_TAG_OP_SWTAG_DESCH = 2L,
  108. /*
  109. * just de-schedule
  110. * - fields used: op, no_sched
  111. */
  112. CVMX_POW_TAG_OP_DESCH = 3L,
  113. /*
  114. * create an entirely new work queue entry
  115. * - fields used: address, op, qos, grp, type, tag
  116. */
  117. CVMX_POW_TAG_OP_ADDWQ = 4L,
  118. /*
  119. * just update the work queue pointer and grp for this PP
  120. * - fields used: address, op, grp
  121. */
  122. CVMX_POW_TAG_OP_UPDATE_WQP_GRP = 5L,
  123. /*
  124. * set the no_sched bit on the de-schedule list
  125. *
  126. * - does nothing if the selected entry is not on the
  127. * de-schedule list
  128. *
  129. * - does nothing if the stored work queue pointer does not
  130. * match the address field
  131. *
  132. * - fields used: address, index, op
  133. *
  134. * Before issuing a *_NSCHED operation, SW must guarantee
  135. * that all prior deschedules and set/clr NSCHED operations
  136. * are complete and all prior switches are complete. The
  137. * hardware provides the opsdone bit and swdone bit for SW
  138. * polling. After issuing a *_NSCHED operation, SW must
  139. * guarantee that the set/clr NSCHED is complete before any
  140. * subsequent operations.
  141. */
  142. CVMX_POW_TAG_OP_SET_NSCHED = 6L,
  143. /*
  144. * clears the no_sched bit on the de-schedule list
  145. *
  146. * - does nothing if the selected entry is not on the
  147. * de-schedule list
  148. *
  149. * - does nothing if the stored work queue pointer does not
  150. * match the address field
  151. *
  152. * - fields used: address, index, op
  153. *
  154. * Before issuing a *_NSCHED operation, SW must guarantee that
  155. * all prior deschedules and set/clr NSCHED operations are
  156. * complete and all prior switches are complete. The hardware
  157. * provides the opsdone bit and swdone bit for SW
  158. * polling. After issuing a *_NSCHED operation, SW must
  159. * guarantee that the set/clr NSCHED is complete before any
  160. * subsequent operations.
  161. */
  162. CVMX_POW_TAG_OP_CLR_NSCHED = 7L,
  163. /* do nothing */
  164. CVMX_POW_TAG_OP_NOP = 15L
  165. } cvmx_pow_tag_op_t;
  166. /**
  167. * This structure defines the store data on a store to POW
  168. */
  169. typedef union {
  170. uint64_t u64;
  171. struct {
  172. /*
  173. * Don't reschedule this entry. no_sched is used for
  174. * CVMX_POW_TAG_OP_SWTAG_DESCH and
  175. * CVMX_POW_TAG_OP_DESCH
  176. */
  177. uint64_t no_sched:1;
  178. uint64_t unused:2;
  179. /* Tontains index of entry for a CVMX_POW_TAG_OP_*_NSCHED */
  180. uint64_t index:13;
  181. /* The operation to perform */
  182. cvmx_pow_tag_op_t op:4;
  183. uint64_t unused2:2;
  184. /*
  185. * The QOS level for the packet. qos is only used for
  186. * CVMX_POW_TAG_OP_ADDWQ
  187. */
  188. uint64_t qos:3;
  189. /*
  190. * The group that the work queue entry will be
  191. * scheduled to grp is used for CVMX_POW_TAG_OP_ADDWQ,
  192. * CVMX_POW_TAG_OP_SWTAG_FULL,
  193. * CVMX_POW_TAG_OP_SWTAG_DESCH, and
  194. * CVMX_POW_TAG_OP_UPDATE_WQP_GRP
  195. */
  196. uint64_t grp:4;
  197. /*
  198. * The type of the tag. type is used for everything
  199. * except CVMX_POW_TAG_OP_DESCH,
  200. * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and
  201. * CVMX_POW_TAG_OP_*_NSCHED
  202. */
  203. uint64_t type:3;
  204. /*
  205. * The actual tag. tag is used for everything except
  206. * CVMX_POW_TAG_OP_DESCH,
  207. * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and
  208. * CVMX_POW_TAG_OP_*_NSCHED
  209. */
  210. uint64_t tag:32;
  211. } s;
  212. } cvmx_pow_tag_req_t;
  213. /**
  214. * This structure describes the address to load stuff from POW
  215. */
  216. typedef union {
  217. uint64_t u64;
  218. /**
  219. * Address for new work request loads (did<2:0> == 0)
  220. */
  221. struct {
  222. /* Mips64 address region. Should be CVMX_IO_SEG */
  223. uint64_t mem_region:2;
  224. /* Must be zero */
  225. uint64_t reserved_49_61:13;
  226. /* Must be one */
  227. uint64_t is_io:1;
  228. /* the ID of POW -- did<2:0> == 0 in this case */
  229. uint64_t did:8;
  230. /* Must be zero */
  231. uint64_t reserved_4_39:36;
  232. /*
  233. * If set, don't return load response until work is
  234. * available.
  235. */
  236. uint64_t wait:1;
  237. /* Must be zero */
  238. uint64_t reserved_0_2:3;
  239. } swork;
  240. /**
  241. * Address for loads to get POW internal status
  242. */
  243. struct {
  244. /* Mips64 address region. Should be CVMX_IO_SEG */
  245. uint64_t mem_region:2;
  246. /* Must be zero */
  247. uint64_t reserved_49_61:13;
  248. /* Must be one */
  249. uint64_t is_io:1;
  250. /* the ID of POW -- did<2:0> == 1 in this case */
  251. uint64_t did:8;
  252. /* Must be zero */
  253. uint64_t reserved_10_39:30;
  254. /* The core id to get status for */
  255. uint64_t coreid:4;
  256. /*
  257. * If set and get_cur is set, return reverse tag-list
  258. * pointer rather than forward tag-list pointer.
  259. */
  260. uint64_t get_rev:1;
  261. /*
  262. * If set, return current status rather than pending
  263. * status.
  264. */
  265. uint64_t get_cur:1;
  266. /*
  267. * If set, get the work-queue pointer rather than
  268. * tag/type.
  269. */
  270. uint64_t get_wqp:1;
  271. /* Must be zero */
  272. uint64_t reserved_0_2:3;
  273. } sstatus;
  274. /**
  275. * Address for memory loads to get POW internal state
  276. */
  277. struct {
  278. /* Mips64 address region. Should be CVMX_IO_SEG */
  279. uint64_t mem_region:2;
  280. /* Must be zero */
  281. uint64_t reserved_49_61:13;
  282. /* Must be one */
  283. uint64_t is_io:1;
  284. /* the ID of POW -- did<2:0> == 2 in this case */
  285. uint64_t did:8;
  286. /* Must be zero */
  287. uint64_t reserved_16_39:24;
  288. /* POW memory index */
  289. uint64_t index:11;
  290. /*
  291. * If set, return deschedule information rather than
  292. * the standard response for work-queue index (invalid
  293. * if the work-queue entry is not on the deschedule
  294. * list).
  295. */
  296. uint64_t get_des:1;
  297. /*
  298. * If set, get the work-queue pointer rather than
  299. * tag/type (no effect when get_des set).
  300. */
  301. uint64_t get_wqp:1;
  302. /* Must be zero */
  303. uint64_t reserved_0_2:3;
  304. } smemload;
  305. /**
  306. * Address for index/pointer loads
  307. */
  308. struct {
  309. /* Mips64 address region. Should be CVMX_IO_SEG */
  310. uint64_t mem_region:2;
  311. /* Must be zero */
  312. uint64_t reserved_49_61:13;
  313. /* Must be one */
  314. uint64_t is_io:1;
  315. /* the ID of POW -- did<2:0> == 3 in this case */
  316. uint64_t did:8;
  317. /* Must be zero */
  318. uint64_t reserved_9_39:31;
  319. /*
  320. * when {get_rmt ==0 AND get_des_get_tail == 0}, this
  321. * field selects one of eight POW internal-input
  322. * queues (0-7), one per QOS level; values 8-15 are
  323. * illegal in this case; when {get_rmt ==0 AND
  324. * get_des_get_tail == 1}, this field selects one of
  325. * 16 deschedule lists (per group); when get_rmt ==1,
  326. * this field selects one of 16 memory-input queue
  327. * lists. The two memory-input queue lists associated
  328. * with each QOS level are:
  329. *
  330. * - qosgrp = 0, qosgrp = 8: QOS0
  331. * - qosgrp = 1, qosgrp = 9: QOS1
  332. * - qosgrp = 2, qosgrp = 10: QOS2
  333. * - qosgrp = 3, qosgrp = 11: QOS3
  334. * - qosgrp = 4, qosgrp = 12: QOS4
  335. * - qosgrp = 5, qosgrp = 13: QOS5
  336. * - qosgrp = 6, qosgrp = 14: QOS6
  337. * - qosgrp = 7, qosgrp = 15: QOS7
  338. */
  339. uint64_t qosgrp:4;
  340. /*
  341. * If set and get_rmt is clear, return deschedule list
  342. * indexes rather than indexes for the specified qos
  343. * level; if set and get_rmt is set, return the tail
  344. * pointer rather than the head pointer for the
  345. * specified qos level.
  346. */
  347. uint64_t get_des_get_tail:1;
  348. /*
  349. * If set, return remote pointers rather than the
  350. * local indexes for the specified qos level.
  351. */
  352. uint64_t get_rmt:1;
  353. /* Must be zero */
  354. uint64_t reserved_0_2:3;
  355. } sindexload;
  356. /**
  357. * address for NULL_RD request (did<2:0> == 4) when this is read,
  358. * HW attempts to change the state to NULL if it is NULL_NULL (the
  359. * hardware cannot switch from NULL_NULL to NULL if a POW entry is
  360. * not available - software may need to recover by finishing
  361. * another piece of work before a POW entry can ever become
  362. * available.)
  363. */
  364. struct {
  365. /* Mips64 address region. Should be CVMX_IO_SEG */
  366. uint64_t mem_region:2;
  367. /* Must be zero */
  368. uint64_t reserved_49_61:13;
  369. /* Must be one */
  370. uint64_t is_io:1;
  371. /* the ID of POW -- did<2:0> == 4 in this case */
  372. uint64_t did:8;
  373. /* Must be zero */
  374. uint64_t reserved_0_39:40;
  375. } snull_rd;
  376. } cvmx_pow_load_addr_t;
  377. /**
  378. * This structure defines the response to a load/SENDSINGLE to POW
  379. * (except CSR reads)
  380. */
  381. typedef union {
  382. uint64_t u64;
  383. /**
  384. * Response to new work request loads
  385. */
  386. struct {
  387. /*
  388. * Set when no new work queue entry was returned. *
  389. * If there was de-scheduled work, the HW will
  390. * definitely return it. When this bit is set, it
  391. * could mean either mean:
  392. *
  393. * - There was no work, or
  394. *
  395. * - There was no work that the HW could find. This
  396. * case can happen, regardless of the wait bit value
  397. * in the original request, when there is work in
  398. * the IQ's that is too deep down the list.
  399. */
  400. uint64_t no_work:1;
  401. /* Must be zero */
  402. uint64_t reserved_40_62:23;
  403. /* 36 in O1 -- the work queue pointer */
  404. uint64_t addr:40;
  405. } s_work;
  406. /**
  407. * Result for a POW Status Load (when get_cur==0 and get_wqp==0)
  408. */
  409. struct {
  410. uint64_t reserved_62_63:2;
  411. /* Set when there is a pending non-NULL SWTAG or
  412. * SWTAG_FULL, and the POW entry has not left the list
  413. * for the original tag. */
  414. uint64_t pend_switch:1;
  415. /* Set when SWTAG_FULL and pend_switch is set. */
  416. uint64_t pend_switch_full:1;
  417. /*
  418. * Set when there is a pending NULL SWTAG, or an
  419. * implicit switch to NULL.
  420. */
  421. uint64_t pend_switch_null:1;
  422. /* Set when there is a pending DESCHED or SWTAG_DESCHED. */
  423. uint64_t pend_desched:1;
  424. /*
  425. * Set when there is a pending SWTAG_DESCHED and
  426. * pend_desched is set.
  427. */
  428. uint64_t pend_desched_switch:1;
  429. /* Set when nosched is desired and pend_desched is set. */
  430. uint64_t pend_nosched:1;
  431. /* Set when there is a pending GET_WORK. */
  432. uint64_t pend_new_work:1;
  433. /*
  434. * When pend_new_work is set, this bit indicates that
  435. * the wait bit was set.
  436. */
  437. uint64_t pend_new_work_wait:1;
  438. /* Set when there is a pending NULL_RD. */
  439. uint64_t pend_null_rd:1;
  440. /* Set when there is a pending CLR_NSCHED. */
  441. uint64_t pend_nosched_clr:1;
  442. uint64_t reserved_51:1;
  443. /* This is the index when pend_nosched_clr is set. */
  444. uint64_t pend_index:11;
  445. /*
  446. * This is the new_grp when (pend_desched AND
  447. * pend_desched_switch) is set.
  448. */
  449. uint64_t pend_grp:4;
  450. uint64_t reserved_34_35:2;
  451. /*
  452. * This is the tag type when pend_switch or
  453. * (pend_desched AND pend_desched_switch) are set.
  454. */
  455. uint64_t pend_type:2;
  456. /*
  457. * - this is the tag when pend_switch or (pend_desched
  458. * AND pend_desched_switch) are set.
  459. */
  460. uint64_t pend_tag:32;
  461. } s_sstatus0;
  462. /**
  463. * Result for a POW Status Load (when get_cur==0 and get_wqp==1)
  464. */
  465. struct {
  466. uint64_t reserved_62_63:2;
  467. /*
  468. * Set when there is a pending non-NULL SWTAG or
  469. * SWTAG_FULL, and the POW entry has not left the list
  470. * for the original tag.
  471. */
  472. uint64_t pend_switch:1;
  473. /* Set when SWTAG_FULL and pend_switch is set. */
  474. uint64_t pend_switch_full:1;
  475. /*
  476. * Set when there is a pending NULL SWTAG, or an
  477. * implicit switch to NULL.
  478. */
  479. uint64_t pend_switch_null:1;
  480. /*
  481. * Set when there is a pending DESCHED or
  482. * SWTAG_DESCHED.
  483. */
  484. uint64_t pend_desched:1;
  485. /*
  486. * Set when there is a pending SWTAG_DESCHED and
  487. * pend_desched is set.
  488. */
  489. uint64_t pend_desched_switch:1;
  490. /* Set when nosched is desired and pend_desched is set. */
  491. uint64_t pend_nosched:1;
  492. /* Set when there is a pending GET_WORK. */
  493. uint64_t pend_new_work:1;
  494. /*
  495. * When pend_new_work is set, this bit indicates that
  496. * the wait bit was set.
  497. */
  498. uint64_t pend_new_work_wait:1;
  499. /* Set when there is a pending NULL_RD. */
  500. uint64_t pend_null_rd:1;
  501. /* Set when there is a pending CLR_NSCHED. */
  502. uint64_t pend_nosched_clr:1;
  503. uint64_t reserved_51:1;
  504. /* This is the index when pend_nosched_clr is set. */
  505. uint64_t pend_index:11;
  506. /*
  507. * This is the new_grp when (pend_desched AND
  508. * pend_desched_switch) is set.
  509. */
  510. uint64_t pend_grp:4;
  511. /* This is the wqp when pend_nosched_clr is set. */
  512. uint64_t pend_wqp:36;
  513. } s_sstatus1;
  514. /**
  515. * Result for a POW Status Load (when get_cur==1, get_wqp==0, and
  516. * get_rev==0)
  517. */
  518. struct {
  519. uint64_t reserved_62_63:2;
  520. /*
  521. * Points to the next POW entry in the tag list when
  522. * tail == 0 (and tag_type is not NULL or NULL_NULL).
  523. */
  524. uint64_t link_index:11;
  525. /* The POW entry attached to the core. */
  526. uint64_t index:11;
  527. /*
  528. * The group attached to the core (updated when new
  529. * tag list entered on SWTAG_FULL).
  530. */
  531. uint64_t grp:4;
  532. /*
  533. * Set when this POW entry is at the head of its tag
  534. * list (also set when in the NULL or NULL_NULL
  535. * state).
  536. */
  537. uint64_t head:1;
  538. /*
  539. * Set when this POW entry is at the tail of its tag
  540. * list (also set when in the NULL or NULL_NULL
  541. * state).
  542. */
  543. uint64_t tail:1;
  544. /*
  545. * The tag type attached to the core (updated when new
  546. * tag list entered on SWTAG, SWTAG_FULL, or
  547. * SWTAG_DESCHED).
  548. */
  549. uint64_t tag_type:2;
  550. /*
  551. * The tag attached to the core (updated when new tag
  552. * list entered on SWTAG, SWTAG_FULL, or
  553. * SWTAG_DESCHED).
  554. */
  555. uint64_t tag:32;
  556. } s_sstatus2;
  557. /**
  558. * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1)
  559. */
  560. struct {
  561. uint64_t reserved_62_63:2;
  562. /*
  563. * Points to the prior POW entry in the tag list when
  564. * head == 0 (and tag_type is not NULL or
  565. * NULL_NULL). This field is unpredictable when the
  566. * core's state is NULL or NULL_NULL.
  567. */
  568. uint64_t revlink_index:11;
  569. /* The POW entry attached to the core. */
  570. uint64_t index:11;
  571. /*
  572. * The group attached to the core (updated when new
  573. * tag list entered on SWTAG_FULL).
  574. */
  575. uint64_t grp:4;
  576. /* Set when this POW entry is at the head of its tag
  577. * list (also set when in the NULL or NULL_NULL
  578. * state).
  579. */
  580. uint64_t head:1;
  581. /*
  582. * Set when this POW entry is at the tail of its tag
  583. * list (also set when in the NULL or NULL_NULL
  584. * state).
  585. */
  586. uint64_t tail:1;
  587. /*
  588. * The tag type attached to the core (updated when new
  589. * tag list entered on SWTAG, SWTAG_FULL, or
  590. * SWTAG_DESCHED).
  591. */
  592. uint64_t tag_type:2;
  593. /*
  594. * The tag attached to the core (updated when new tag
  595. * list entered on SWTAG, SWTAG_FULL, or
  596. * SWTAG_DESCHED).
  597. */
  598. uint64_t tag:32;
  599. } s_sstatus3;
  600. /**
  601. * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
  602. * get_rev==0)
  603. */
  604. struct {
  605. uint64_t reserved_62_63:2;
  606. /*
  607. * Points to the next POW entry in the tag list when
  608. * tail == 0 (and tag_type is not NULL or NULL_NULL).
  609. */
  610. uint64_t link_index:11;
  611. /* The POW entry attached to the core. */
  612. uint64_t index:11;
  613. /*
  614. * The group attached to the core (updated when new
  615. * tag list entered on SWTAG_FULL).
  616. */
  617. uint64_t grp:4;
  618. /*
  619. * The wqp attached to the core (updated when new tag
  620. * list entered on SWTAG_FULL).
  621. */
  622. uint64_t wqp:36;
  623. } s_sstatus4;
  624. /**
  625. * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
  626. * get_rev==1)
  627. */
  628. struct {
  629. uint64_t reserved_62_63:2;
  630. /*
  631. * Points to the prior POW entry in the tag list when
  632. * head == 0 (and tag_type is not NULL or
  633. * NULL_NULL). This field is unpredictable when the
  634. * core's state is NULL or NULL_NULL.
  635. */
  636. uint64_t revlink_index:11;
  637. /* The POW entry attached to the core. */
  638. uint64_t index:11;
  639. /*
  640. * The group attached to the core (updated when new
  641. * tag list entered on SWTAG_FULL).
  642. */
  643. uint64_t grp:4;
  644. /*
  645. * The wqp attached to the core (updated when new tag
  646. * list entered on SWTAG_FULL).
  647. */
  648. uint64_t wqp:36;
  649. } s_sstatus5;
  650. /**
  651. * Result For POW Memory Load (get_des == 0 and get_wqp == 0)
  652. */
  653. struct {
  654. uint64_t reserved_51_63:13;
  655. /*
  656. * The next entry in the input, free, descheduled_head
  657. * list (unpredictable if entry is the tail of the
  658. * list).
  659. */
  660. uint64_t next_index:11;
  661. /* The group of the POW entry. */
  662. uint64_t grp:4;
  663. uint64_t reserved_35:1;
  664. /*
  665. * Set when this POW entry is at the tail of its tag
  666. * list (also set when in the NULL or NULL_NULL
  667. * state).
  668. */
  669. uint64_t tail:1;
  670. /* The tag type of the POW entry. */
  671. uint64_t tag_type:2;
  672. /* The tag of the POW entry. */
  673. uint64_t tag:32;
  674. } s_smemload0;
  675. /**
  676. * Result For POW Memory Load (get_des == 0 and get_wqp == 1)
  677. */
  678. struct {
  679. uint64_t reserved_51_63:13;
  680. /*
  681. * The next entry in the input, free, descheduled_head
  682. * list (unpredictable if entry is the tail of the
  683. * list).
  684. */
  685. uint64_t next_index:11;
  686. /* The group of the POW entry. */
  687. uint64_t grp:4;
  688. /* The WQP held in the POW entry. */
  689. uint64_t wqp:36;
  690. } s_smemload1;
  691. /**
  692. * Result For POW Memory Load (get_des == 1)
  693. */
  694. struct {
  695. uint64_t reserved_51_63:13;
  696. /*
  697. * The next entry in the tag list connected to the
  698. * descheduled head.
  699. */
  700. uint64_t fwd_index:11;
  701. /* The group of the POW entry. */
  702. uint64_t grp:4;
  703. /* The nosched bit for the POW entry. */
  704. uint64_t nosched:1;
  705. /* There is a pending tag switch */
  706. uint64_t pend_switch:1;
  707. /*
  708. * The next tag type for the new tag list when
  709. * pend_switch is set.
  710. */
  711. uint64_t pend_type:2;
  712. /*
  713. * The next tag for the new tag list when pend_switch
  714. * is set.
  715. */
  716. uint64_t pend_tag:32;
  717. } s_smemload2;
  718. /**
  719. * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0)
  720. */
  721. struct {
  722. uint64_t reserved_52_63:12;
  723. /*
  724. * set when there is one or more POW entries on the
  725. * free list.
  726. */
  727. uint64_t free_val:1;
  728. /*
  729. * set when there is exactly one POW entry on the free
  730. * list.
  731. */
  732. uint64_t free_one:1;
  733. uint64_t reserved_49:1;
  734. /*
  735. * when free_val is set, indicates the first entry on
  736. * the free list.
  737. */
  738. uint64_t free_head:11;
  739. uint64_t reserved_37:1;
  740. /*
  741. * when free_val is set, indicates the last entry on
  742. * the free list.
  743. */
  744. uint64_t free_tail:11;
  745. /*
  746. * set when there is one or more POW entries on the
  747. * input Q list selected by qosgrp.
  748. */
  749. uint64_t loc_val:1;
  750. /*
  751. * set when there is exactly one POW entry on the
  752. * input Q list selected by qosgrp.
  753. */
  754. uint64_t loc_one:1;
  755. uint64_t reserved_23:1;
  756. /*
  757. * when loc_val is set, indicates the first entry on
  758. * the input Q list selected by qosgrp.
  759. */
  760. uint64_t loc_head:11;
  761. uint64_t reserved_11:1;
  762. /*
  763. * when loc_val is set, indicates the last entry on
  764. * the input Q list selected by qosgrp.
  765. */
  766. uint64_t loc_tail:11;
  767. } sindexload0;
  768. /**
  769. * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1)
  770. */
  771. struct {
  772. uint64_t reserved_52_63:12;
  773. /*
  774. * set when there is one or more POW entries on the
  775. * nosched list.
  776. */
  777. uint64_t nosched_val:1;
  778. /*
  779. * set when there is exactly one POW entry on the
  780. * nosched list.
  781. */
  782. uint64_t nosched_one:1;
  783. uint64_t reserved_49:1;
  784. /*
  785. * when nosched_val is set, indicates the first entry
  786. * on the nosched list.
  787. */
  788. uint64_t nosched_head:11;
  789. uint64_t reserved_37:1;
  790. /*
  791. * when nosched_val is set, indicates the last entry
  792. * on the nosched list.
  793. */
  794. uint64_t nosched_tail:11;
  795. /*
  796. * set when there is one or more descheduled heads on
  797. * the descheduled list selected by qosgrp.
  798. */
  799. uint64_t des_val:1;
  800. /*
  801. * set when there is exactly one descheduled head on
  802. * the descheduled list selected by qosgrp.
  803. */
  804. uint64_t des_one:1;
  805. uint64_t reserved_23:1;
  806. /*
  807. * when des_val is set, indicates the first
  808. * descheduled head on the descheduled list selected
  809. * by qosgrp.
  810. */
  811. uint64_t des_head:11;
  812. uint64_t reserved_11:1;
  813. /*
  814. * when des_val is set, indicates the last descheduled
  815. * head on the descheduled list selected by qosgrp.
  816. */
  817. uint64_t des_tail:11;
  818. } sindexload1;
  819. /**
  820. * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0)
  821. */
  822. struct {
  823. uint64_t reserved_39_63:25;
  824. /*
  825. * Set when this DRAM list is the current head
  826. * (i.e. is the next to be reloaded when the POW
  827. * hardware reloads a POW entry from DRAM). The POW
  828. * hardware alternates between the two DRAM lists
  829. * associated with a QOS level when it reloads work
  830. * from DRAM into the POW unit.
  831. */
  832. uint64_t rmt_is_head:1;
  833. /*
  834. * Set when the DRAM portion of the input Q list
  835. * selected by qosgrp contains one or more pieces of
  836. * work.
  837. */
  838. uint64_t rmt_val:1;
  839. /*
  840. * Set when the DRAM portion of the input Q list
  841. * selected by qosgrp contains exactly one piece of
  842. * work.
  843. */
  844. uint64_t rmt_one:1;
  845. /*
  846. * When rmt_val is set, indicates the first piece of
  847. * work on the DRAM input Q list selected by
  848. * qosgrp.
  849. */
  850. uint64_t rmt_head:36;
  851. } sindexload2;
  852. /**
  853. * Result For POW Index/Pointer Load (get_rmt ==
  854. * 1/get_des_get_tail == 1)
  855. */
  856. struct {
  857. uint64_t reserved_39_63:25;
  858. /*
  859. * set when this DRAM list is the current head
  860. * (i.e. is the next to be reloaded when the POW
  861. * hardware reloads a POW entry from DRAM). The POW
  862. * hardware alternates between the two DRAM lists
  863. * associated with a QOS level when it reloads work
  864. * from DRAM into the POW unit.
  865. */
  866. uint64_t rmt_is_head:1;
  867. /*
  868. * set when the DRAM portion of the input Q list
  869. * selected by qosgrp contains one or more pieces of
  870. * work.
  871. */
  872. uint64_t rmt_val:1;
  873. /*
  874. * set when the DRAM portion of the input Q list
  875. * selected by qosgrp contains exactly one piece of
  876. * work.
  877. */
  878. uint64_t rmt_one:1;
  879. /*
  880. * when rmt_val is set, indicates the last piece of
  881. * work on the DRAM input Q list selected by
  882. * qosgrp.
  883. */
  884. uint64_t rmt_tail:36;
  885. } sindexload3;
  886. /**
  887. * Response to NULL_RD request loads
  888. */
  889. struct {
  890. uint64_t unused:62;
  891. /* of type cvmx_pow_tag_type_t. state is one of the
  892. * following:
  893. *
  894. * - CVMX_POW_TAG_TYPE_ORDERED
  895. * - CVMX_POW_TAG_TYPE_ATOMIC
  896. * - CVMX_POW_TAG_TYPE_NULL
  897. * - CVMX_POW_TAG_TYPE_NULL_NULL
  898. */
  899. uint64_t state:2;
  900. } s_null_rd;
  901. } cvmx_pow_tag_load_resp_t;
  902. /**
  903. * This structure describes the address used for stores to the POW.
  904. * The store address is meaningful on stores to the POW. The
  905. * hardware assumes that an aligned 64-bit store was used for all
  906. * these stores. Note the assumption that the work queue entry is
  907. * aligned on an 8-byte boundary (since the low-order 3 address bits
  908. * must be zero). Note that not all fields are used by all
  909. * operations.
  910. *
  911. * NOTE: The following is the behavior of the pending switch bit at the PP
  912. * for POW stores (i.e. when did<7:3> == 0xc)
  913. * - did<2:0> == 0 => pending switch bit is set
  914. * - did<2:0> == 1 => no affect on the pending switch bit
  915. * - did<2:0> == 3 => pending switch bit is cleared
  916. * - did<2:0> == 7 => no affect on the pending switch bit
  917. * - did<2:0> == others => must not be used
  918. * - No other loads/stores have an affect on the pending switch bit
  919. * - The switch bus from POW can clear the pending switch bit
  920. *
  921. * NOTE: did<2:0> == 2 is used by the HW for a special single-cycle
  922. * ADDWQ command that only contains the pointer). SW must never use
  923. * did<2:0> == 2.
  924. */
  925. typedef union {
  926. /**
  927. * Unsigned 64 bit integer representation of store address
  928. */
  929. uint64_t u64;
  930. struct {
  931. /* Memory region. Should be CVMX_IO_SEG in most cases */
  932. uint64_t mem_reg:2;
  933. uint64_t reserved_49_61:13; /* Must be zero */
  934. uint64_t is_io:1; /* Must be one */
  935. /* Device ID of POW. Note that different sub-dids are used. */
  936. uint64_t did:8;
  937. uint64_t reserved_36_39:4; /* Must be zero */
  938. /* Address field. addr<2:0> must be zero */
  939. uint64_t addr:36;
  940. } stag;
  941. } cvmx_pow_tag_store_addr_t;
  942. /**
  943. * decode of the store data when an IOBDMA SENDSINGLE is sent to POW
  944. */
  945. typedef union {
  946. uint64_t u64;
  947. struct {
  948. /*
  949. * the (64-bit word) location in scratchpad to write
  950. * to (if len != 0)
  951. */
  952. uint64_t scraddr:8;
  953. /* the number of words in the response (0 => no response) */
  954. uint64_t len:8;
  955. /* the ID of the device on the non-coherent bus */
  956. uint64_t did:8;
  957. uint64_t unused:36;
  958. /* if set, don't return load response until work is available */
  959. uint64_t wait:1;
  960. uint64_t unused2:3;
  961. } s;
  962. } cvmx_pow_iobdma_store_t;
  963. /* CSR typedefs have been moved to cvmx-csr-*.h */
  964. /**
  965. * Get the POW tag for this core. This returns the current
  966. * tag type, tag, group, and POW entry index associated with
  967. * this core. Index is only valid if the tag type isn't NULL_NULL.
  968. * If a tag switch is pending this routine returns the tag before
  969. * the tag switch, not after.
  970. *
  971. * Returns Current tag
  972. */
  973. static inline cvmx_pow_tag_req_t cvmx_pow_get_current_tag(void)
  974. {
  975. cvmx_pow_load_addr_t load_addr;
  976. cvmx_pow_tag_load_resp_t load_resp;
  977. cvmx_pow_tag_req_t result;
  978. load_addr.u64 = 0;
  979. load_addr.sstatus.mem_region = CVMX_IO_SEG;
  980. load_addr.sstatus.is_io = 1;
  981. load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
  982. load_addr.sstatus.coreid = cvmx_get_core_num();
  983. load_addr.sstatus.get_cur = 1;
  984. load_resp.u64 = cvmx_read_csr(load_addr.u64);
  985. result.u64 = 0;
  986. result.s.grp = load_resp.s_sstatus2.grp;
  987. result.s.index = load_resp.s_sstatus2.index;
  988. result.s.type = load_resp.s_sstatus2.tag_type;
  989. result.s.tag = load_resp.s_sstatus2.tag;
  990. return result;
  991. }
  992. /**
  993. * Get the POW WQE for this core. This returns the work queue
  994. * entry currently associated with this core.
  995. *
  996. * Returns WQE pointer
  997. */
  998. static inline cvmx_wqe_t *cvmx_pow_get_current_wqp(void)
  999. {
  1000. cvmx_pow_load_addr_t load_addr;
  1001. cvmx_pow_tag_load_resp_t load_resp;
  1002. load_addr.u64 = 0;
  1003. load_addr.sstatus.mem_region = CVMX_IO_SEG;
  1004. load_addr.sstatus.is_io = 1;
  1005. load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
  1006. load_addr.sstatus.coreid = cvmx_get_core_num();
  1007. load_addr.sstatus.get_cur = 1;
  1008. load_addr.sstatus.get_wqp = 1;
  1009. load_resp.u64 = cvmx_read_csr(load_addr.u64);
  1010. return (cvmx_wqe_t *) cvmx_phys_to_ptr(load_resp.s_sstatus4.wqp);
  1011. }
  1012. #ifndef CVMX_MF_CHORD
  1013. #define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30)
  1014. #endif
  1015. /**
  1016. * Print a warning if a tag switch is pending for this core
  1017. *
  1018. * @function: Function name checking for a pending tag switch
  1019. */
  1020. static inline void __cvmx_pow_warn_if_pending_switch(const char *function)
  1021. {
  1022. uint64_t switch_complete;
  1023. CVMX_MF_CHORD(switch_complete);
  1024. if (!switch_complete)
  1025. pr_warning("%s called with tag switch in progress\n", function);
  1026. }
  1027. /**
  1028. * Waits for a tag switch to complete by polling the completion bit.
  1029. * Note that switches to NULL complete immediately and do not need
  1030. * to be waited for.
  1031. */
  1032. static inline void cvmx_pow_tag_sw_wait(void)
  1033. {
  1034. const uint64_t MAX_CYCLES = 1ull << 31;
  1035. uint64_t switch_complete;
  1036. uint64_t start_cycle = cvmx_get_cycle();
  1037. while (1) {
  1038. CVMX_MF_CHORD(switch_complete);
  1039. if (unlikely(switch_complete))
  1040. break;
  1041. if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) {
  1042. pr_warning("Tag switch is taking a long time, "
  1043. "possible deadlock\n");
  1044. start_cycle = -MAX_CYCLES - 1;
  1045. }
  1046. }
  1047. }
  1048. /**
  1049. * Synchronous work request. Requests work from the POW.
  1050. * This function does NOT wait for previous tag switches to complete,
  1051. * so the caller must ensure that there is not a pending tag switch.
  1052. *
  1053. * @wait: When set, call stalls until work becomes avaiable, or times out.
  1054. * If not set, returns immediately.
  1055. *
  1056. * Returns Returns the WQE pointer from POW. Returns NULL if no work
  1057. * was available.
  1058. */
  1059. static inline cvmx_wqe_t *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t
  1060. wait)
  1061. {
  1062. cvmx_pow_load_addr_t ptr;
  1063. cvmx_pow_tag_load_resp_t result;
  1064. if (CVMX_ENABLE_POW_CHECKS)
  1065. __cvmx_pow_warn_if_pending_switch(__func__);
  1066. ptr.u64 = 0;
  1067. ptr.swork.mem_region = CVMX_IO_SEG;
  1068. ptr.swork.is_io = 1;
  1069. ptr.swork.did = CVMX_OCT_DID_TAG_SWTAG;
  1070. ptr.swork.wait = wait;
  1071. result.u64 = cvmx_read_csr(ptr.u64);
  1072. if (result.s_work.no_work)
  1073. return NULL;
  1074. else
  1075. return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
  1076. }
  1077. /**
  1078. * Synchronous work request. Requests work from the POW.
  1079. * This function waits for any previous tag switch to complete before
  1080. * requesting the new work.
  1081. *
  1082. * @wait: When set, call stalls until work becomes avaiable, or times out.
  1083. * If not set, returns immediately.
  1084. *
  1085. * Returns Returns the WQE pointer from POW. Returns NULL if no work
  1086. * was available.
  1087. */
  1088. static inline cvmx_wqe_t *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait)
  1089. {
  1090. if (CVMX_ENABLE_POW_CHECKS)
  1091. __cvmx_pow_warn_if_pending_switch(__func__);
  1092. /* Must not have a switch pending when requesting work */
  1093. cvmx_pow_tag_sw_wait();
  1094. return cvmx_pow_work_request_sync_nocheck(wait);
  1095. }
  1096. /**
  1097. * Synchronous null_rd request. Requests a switch out of NULL_NULL POW state.
  1098. * This function waits for any previous tag switch to complete before
  1099. * requesting the null_rd.
  1100. *
  1101. * Returns Returns the POW state of type cvmx_pow_tag_type_t.
  1102. */
  1103. static inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void)
  1104. {
  1105. cvmx_pow_load_addr_t ptr;
  1106. cvmx_pow_tag_load_resp_t result;
  1107. if (CVMX_ENABLE_POW_CHECKS)
  1108. __cvmx_pow_warn_if_pending_switch(__func__);
  1109. /* Must not have a switch pending when requesting work */
  1110. cvmx_pow_tag_sw_wait();
  1111. ptr.u64 = 0;
  1112. ptr.snull_rd.mem_region = CVMX_IO_SEG;
  1113. ptr.snull_rd.is_io = 1;
  1114. ptr.snull_rd.did = CVMX_OCT_DID_TAG_NULL_RD;
  1115. result.u64 = cvmx_read_csr(ptr.u64);
  1116. return (enum cvmx_pow_tag_type) result.s_null_rd.state;
  1117. }
  1118. /**
  1119. * Asynchronous work request. Work is requested from the POW unit,
  1120. * and should later be checked with function
  1121. * cvmx_pow_work_response_async. This function does NOT wait for
  1122. * previous tag switches to complete, so the caller must ensure that
  1123. * there is not a pending tag switch.
  1124. *
  1125. * @scr_addr: Scratch memory address that response will be returned
  1126. * to, which is either a valid WQE, or a response with the
  1127. * invalid bit set. Byte address, must be 8 byte aligned.
  1128. *
  1129. * @wait: 1 to cause response to wait for work to become available (or
  1130. * timeout), 0 to cause response to return immediately
  1131. */
  1132. static inline void cvmx_pow_work_request_async_nocheck(int scr_addr,
  1133. cvmx_pow_wait_t wait)
  1134. {
  1135. cvmx_pow_iobdma_store_t data;
  1136. if (CVMX_ENABLE_POW_CHECKS)
  1137. __cvmx_pow_warn_if_pending_switch(__func__);
  1138. /* scr_addr must be 8 byte aligned */
  1139. data.s.scraddr = scr_addr >> 3;
  1140. data.s.len = 1;
  1141. data.s.did = CVMX_OCT_DID_TAG_SWTAG;
  1142. data.s.wait = wait;
  1143. cvmx_send_single(data.u64);
  1144. }
  1145. /**
  1146. * Asynchronous work request. Work is requested from the POW unit,
  1147. * and should later be checked with function
  1148. * cvmx_pow_work_response_async. This function waits for any previous
  1149. * tag switch to complete before requesting the new work.
  1150. *
  1151. * @scr_addr: Scratch memory address that response will be returned
  1152. * to, which is either a valid WQE, or a response with the
  1153. * invalid bit set. Byte address, must be 8 byte aligned.
  1154. *
  1155. * @wait: 1 to cause response to wait for work to become available (or
  1156. * timeout), 0 to cause response to return immediately
  1157. */
  1158. static inline void cvmx_pow_work_request_async(int scr_addr,
  1159. cvmx_pow_wait_t wait)
  1160. {
  1161. if (CVMX_ENABLE_POW_CHECKS)
  1162. __cvmx_pow_warn_if_pending_switch(__func__);
  1163. /* Must not have a switch pending when requesting work */
  1164. cvmx_pow_tag_sw_wait();
  1165. cvmx_pow_work_request_async_nocheck(scr_addr, wait);
  1166. }
  1167. /**
  1168. * Gets result of asynchronous work request. Performs a IOBDMA sync
  1169. * to wait for the response.
  1170. *
  1171. * @scr_addr: Scratch memory address to get result from Byte address,
  1172. * must be 8 byte aligned.
  1173. *
  1174. * Returns Returns the WQE from the scratch register, or NULL if no
  1175. * work was available.
  1176. */
  1177. static inline cvmx_wqe_t *cvmx_pow_work_response_async(int scr_addr)
  1178. {
  1179. cvmx_pow_tag_load_resp_t result;
  1180. CVMX_SYNCIOBDMA;
  1181. result.u64 = cvmx_scratch_read64(scr_addr);
  1182. if (result.s_work.no_work)
  1183. return NULL;
  1184. else
  1185. return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
  1186. }
  1187. /**
  1188. * Checks if a work queue entry pointer returned by a work
  1189. * request is valid. It may be invalid due to no work
  1190. * being available or due to a timeout.
  1191. *
  1192. * @wqe_ptr: pointer to a work queue entry returned by the POW
  1193. *
  1194. * Returns 0 if pointer is valid
  1195. * 1 if invalid (no work was returned)
  1196. */
  1197. static inline uint64_t cvmx_pow_work_invalid(cvmx_wqe_t *wqe_ptr)
  1198. {
  1199. return wqe_ptr == NULL;
  1200. }
  1201. /**
  1202. * Starts a tag switch to the provided tag value and tag type.
  1203. * Completion for the tag switch must be checked for separately. This
  1204. * function does NOT update the work queue entry in dram to match tag
  1205. * value and type, so the application must keep track of these if they
  1206. * are important to the application. This tag switch command must not
  1207. * be used for switches to NULL, as the tag switch pending bit will be
  1208. * set by the switch request, but never cleared by the hardware.
  1209. *
  1210. * NOTE: This should not be used when switching from a NULL tag. Use
  1211. * cvmx_pow_tag_sw_full() instead.
  1212. *
  1213. * This function does no checks, so the caller must ensure that any
  1214. * previous tag switch has completed.
  1215. *
  1216. * @tag: new tag value
  1217. * @tag_type: new tag type (ordered or atomic)
  1218. */
  1219. static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag,
  1220. enum cvmx_pow_tag_type tag_type)
  1221. {
  1222. cvmx_addr_t ptr;
  1223. cvmx_pow_tag_req_t tag_req;
  1224. if (CVMX_ENABLE_POW_CHECKS) {
  1225. cvmx_pow_tag_req_t current_tag;
  1226. __cvmx_pow_warn_if_pending_switch(__func__);
  1227. current_tag = cvmx_pow_get_current_tag();
  1228. if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
  1229. pr_warning("%s called with NULL_NULL tag\n",
  1230. __func__);
  1231. if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
  1232. pr_warning("%s called with NULL tag\n", __func__);
  1233. if ((current_tag.s.type == tag_type)
  1234. && (current_tag.s.tag == tag))
  1235. pr_warning("%s called to perform a tag switch to the "
  1236. "same tag\n",
  1237. __func__);
  1238. if (tag_type == CVMX_POW_TAG_TYPE_NULL)
  1239. pr_warning("%s called to perform a tag switch to "
  1240. "NULL. Use cvmx_pow_tag_sw_null() instead\n",
  1241. __func__);
  1242. }
  1243. /*
  1244. * Note that WQE in DRAM is not updated here, as the POW does
  1245. * not read from DRAM once the WQE is in flight. See hardware
  1246. * manual for complete details. It is the application's
  1247. * responsibility to keep track of the current tag value if
  1248. * that is important.
  1249. */
  1250. tag_req.u64 = 0;
  1251. tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
  1252. tag_req.s.tag = tag;
  1253. tag_req.s.type = tag_type;
  1254. ptr.u64 = 0;
  1255. ptr.sio.mem_region = CVMX_IO_SEG;
  1256. ptr.sio.is_io = 1;
  1257. ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
  1258. /* once this store arrives at POW, it will attempt the switch
  1259. software must wait for the switch to complete separately */
  1260. cvmx_write_io(ptr.u64, tag_req.u64);
  1261. }
  1262. /**
  1263. * Starts a tag switch to the provided tag value and tag type.
  1264. * Completion for the tag switch must be checked for separately. This
  1265. * function does NOT update the work queue entry in dram to match tag
  1266. * value and type, so the application must keep track of these if they
  1267. * are important to the application. This tag switch command must not
  1268. * be used for switches to NULL, as the tag switch pending bit will be
  1269. * set by the switch request, but never cleared by the hardware.
  1270. *
  1271. * NOTE: This should not be used when switching from a NULL tag. Use
  1272. * cvmx_pow_tag_sw_full() instead.
  1273. *
  1274. * This function waits for any previous tag switch to complete, and also
  1275. * displays an error on tag switches to NULL.
  1276. *
  1277. * @tag: new tag value
  1278. * @tag_type: new tag type (ordered or atomic)
  1279. */
  1280. static inline void cvmx_pow_tag_sw(uint32_t tag,
  1281. enum cvmx_pow_tag_type tag_type)
  1282. {
  1283. if (CVMX_ENABLE_POW_CHECKS)
  1284. __cvmx_pow_warn_if_pending_switch(__func__);
  1285. /*
  1286. * Note that WQE in DRAM is not updated here, as the POW does
  1287. * not read from DRAM once the WQE is in flight. See hardware
  1288. * manual for complete details. It is the application's
  1289. * responsibility to keep track of the current tag value if
  1290. * that is important.
  1291. */
  1292. /*
  1293. * Ensure that there is not a pending tag switch, as a tag
  1294. * switch cannot be started if a previous switch is still
  1295. * pending.
  1296. */
  1297. cvmx_pow_tag_sw_wait();
  1298. cvmx_pow_tag_sw_nocheck(tag, tag_type);
  1299. }
  1300. /**
  1301. * Starts a tag switch to the provided tag value and tag type.
  1302. * Completion for the tag switch must be checked for separately. This
  1303. * function does NOT update the work queue entry in dram to match tag
  1304. * value and type, so the application must keep track of these if they
  1305. * are important to the application. This tag switch command must not
  1306. * be used for switches to NULL, as the tag switch pending bit will be
  1307. * set by the switch request, but never cleared by the hardware.
  1308. *
  1309. * This function must be used for tag switches from NULL.
  1310. *
  1311. * This function does no checks, so the caller must ensure that any
  1312. * previous tag switch has completed.
  1313. *
  1314. * @wqp: pointer to work queue entry to submit. This entry is
  1315. * updated to match the other parameters
  1316. * @tag: tag value to be assigned to work queue entry
  1317. * @tag_type: type of tag
  1318. * @group: group value for the work queue entry.
  1319. */
  1320. static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag,
  1321. enum cvmx_pow_tag_type tag_type,
  1322. uint64_t group)
  1323. {
  1324. cvmx_addr_t ptr;
  1325. cvmx_pow_tag_req_t tag_req;
  1326. if (CVMX_ENABLE_POW_CHECKS) {
  1327. cvmx_pow_tag_req_t current_tag;
  1328. __cvmx_pow_warn_if_pending_switch(__func__);
  1329. current_tag = cvmx_pow_get_current_tag();
  1330. if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
  1331. pr_warning("%s called with NULL_NULL tag\n",
  1332. __func__);
  1333. if ((current_tag.s.type == tag_type)
  1334. && (current_tag.s.tag == tag))
  1335. pr_warning("%s called to perform a tag switch to "
  1336. "the same tag\n",
  1337. __func__);
  1338. if (tag_type == CVMX_POW_TAG_TYPE_NULL)
  1339. pr_warning("%s called to perform a tag switch to "
  1340. "NULL. Use cvmx_pow_tag_sw_null() instead\n",
  1341. __func__);
  1342. if (wqp != cvmx_phys_to_ptr(0x80))
  1343. if (wqp != cvmx_pow_get_current_wqp())
  1344. pr_warning("%s passed WQE(%p) doesn't match "
  1345. "the address in the POW(%p)\n",
  1346. __func__, wqp,
  1347. cvmx_pow_get_current_wqp());
  1348. }
  1349. /*
  1350. * Note that WQE in DRAM is not updated here, as the POW does
  1351. * not read from DRAM once the WQE is in flight. See hardware
  1352. * manual for complete details. It is the application's
  1353. * responsibility to keep track of the current tag value if
  1354. * that is important.
  1355. */
  1356. tag_req.u64 = 0;
  1357. tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_FULL;
  1358. tag_req.s.tag = tag;
  1359. tag_req.s.type = tag_type;
  1360. tag_req.s.grp = group;
  1361. ptr.u64 = 0;
  1362. ptr.sio.mem_region = CVMX_IO_SEG;
  1363. ptr.sio.is_io = 1;
  1364. ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
  1365. ptr.sio.offset = CAST64(wqp);
  1366. /*
  1367. * once this store arrives at POW, it will attempt the switch
  1368. * software must wait for the switch to complete separately.
  1369. */
  1370. cvmx_write_io(ptr.u64, tag_req.u64);
  1371. }
  1372. /**
  1373. * Starts a tag switch to the provided tag value and tag type.
  1374. * Completion for the tag switch must be checked for separately. This
  1375. * function does NOT update the work queue entry in dram to match tag
  1376. * value and type, so the application must keep track of these if they
  1377. * are important to the application. This tag switch command must not
  1378. * be used for switches to NULL, as the tag switch pending bit will be
  1379. * set by the switch request, but never cleared by the hardware.
  1380. *
  1381. * This function must be used for tag switches from NULL.
  1382. *
  1383. * This function waits for any pending tag switches to complete
  1384. * before requesting the tag switch.
  1385. *
  1386. * @wqp: pointer to work queue entry to submit. This entry is updated
  1387. * to match the other parameters
  1388. * @tag: tag value to be assigned to work queue entry
  1389. * @tag_type: type of tag
  1390. * @group: group value for the work queue entry.
  1391. */
  1392. static inline void cvmx_pow_tag_sw_full(cvmx_wqe_t *wqp, uint32_t tag,
  1393. enum cvmx_pow_tag_type tag_type,
  1394. uint64_t group)
  1395. {
  1396. if (CVMX_ENABLE_POW_CHECKS)
  1397. __cvmx_pow_warn_if_pending_switch(__func__);
  1398. /*
  1399. * Ensure that there is not a pending tag switch, as a tag
  1400. * switch cannot be started if a previous switch is still
  1401. * pending.
  1402. */
  1403. cvmx_pow_tag_sw_wait();
  1404. cvmx_pow_tag_sw_full_nocheck(wqp, tag, tag_type, group);
  1405. }
  1406. /**
  1407. * Switch to a NULL tag, which ends any ordering or
  1408. * synchronization provided by the POW for the current
  1409. * work queue entry. This operation completes immediately,
  1410. * so completion should not be waited for.
  1411. * This function does NOT wait for previous tag switches to complete,
  1412. * so the caller must ensure that any previous tag switches have completed.
  1413. */
  1414. static inline void cvmx_pow_tag_sw_null_nocheck(void)
  1415. {
  1416. cvmx_addr_t ptr;
  1417. cvmx_pow_tag_req_t tag_req;
  1418. if (CVMX_ENABLE_POW_CHECKS) {
  1419. cvmx_pow_tag_req_t current_tag;
  1420. __cvmx_pow_warn_if_pending_switch(__func__);
  1421. current_tag = cvmx_pow_get_current_tag();
  1422. if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
  1423. pr_warning("%s called with NULL_NULL tag\n",
  1424. __func__);
  1425. if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
  1426. pr_warning("%s called when we already have a "
  1427. "NULL tag\n",
  1428. __func__);
  1429. }
  1430. tag_req.u64 = 0;
  1431. tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
  1432. tag_req.s.type = CVMX_POW_TAG_TYPE_NULL;
  1433. ptr.u64 = 0;
  1434. ptr.sio.mem_region = CVMX_IO_SEG;
  1435. ptr.sio.is_io = 1;
  1436. ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
  1437. cvmx_write_io(ptr.u64, tag_req.u64);
  1438. /* switch to NULL completes immediately */
  1439. }
  1440. /**
  1441. * Switch to a NULL tag, which ends any ordering or
  1442. * synchronization provided by the POW for the current
  1443. * work queue entry. This operation completes immediately,
  1444. * so completion should not be waited for.
  1445. * This function waits for any pending tag switches to complete
  1446. * before requesting the switch to NULL.
  1447. */
  1448. static inline void cvmx_pow_tag_sw_null(void)
  1449. {
  1450. if (CVMX_ENABLE_POW_CHECKS)
  1451. __cvmx_pow_warn_if_pending_switch(__func__);
  1452. /*
  1453. * Ensure that there is not a pending tag switch, as a tag
  1454. * switch cannot be started if a previous switch is still
  1455. * pending.
  1456. */
  1457. cvmx_pow_tag_sw_wait();
  1458. cvmx_pow_tag_sw_null_nocheck();
  1459. /* switch to NULL completes immediately */
  1460. }
  1461. /**
  1462. * Submits work to an input queue. This function updates the work
  1463. * queue entry in DRAM to match the arguments given. Note that the
  1464. * tag provided is for the work queue entry submitted, and is
  1465. * unrelated to the tag that the core currently holds.
  1466. *
  1467. * @wqp: pointer to work queue entry to submit. This entry is
  1468. * updated to match the other parameters
  1469. * @tag: tag value to be assigned to work queue entry
  1470. * @tag_type: type of tag
  1471. * @qos: Input queue to add to.
  1472. * @grp: group value for the work queue entry.
  1473. */
  1474. static inline void cvmx_pow_work_submit(cvmx_wqe_t *wqp, uint32_t tag,
  1475. enum cvmx_pow_tag_type tag_type,
  1476. uint64_t qos, uint64_t grp)
  1477. {
  1478. cvmx_addr_t ptr;
  1479. cvmx_pow_tag_req_t tag_req;
  1480. wqp->qos = qos;
  1481. wqp->tag = tag;
  1482. wqp->tag_type = tag_type;
  1483. wqp->grp = grp;
  1484. tag_req.u64 = 0;
  1485. tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ;
  1486. tag_req.s.type = tag_type;
  1487. tag_req.s.tag = tag;
  1488. tag_req.s.qos = qos;
  1489. tag_req.s.grp = grp;
  1490. ptr.u64 = 0;
  1491. ptr.sio.mem_region = CVMX_IO_SEG;
  1492. ptr.sio.is_io = 1;
  1493. ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
  1494. ptr.sio.offset = cvmx_ptr_to_phys(wqp);
  1495. /*
  1496. * SYNC write to memory before the work submit. This is
  1497. * necessary as POW may read values from DRAM at this time.
  1498. */
  1499. CVMX_SYNCWS;
  1500. cvmx_write_io(ptr.u64, tag_req.u64);
  1501. }
  1502. /**
  1503. * This function sets the group mask for a core. The group mask
  1504. * indicates which groups each core will accept work from. There are
  1505. * 16 groups.
  1506. *
  1507. * @core_num: core to apply mask to
  1508. * @mask: Group mask. There are 16 groups, so only bits 0-15 are valid,
  1509. * representing groups 0-15.
  1510. * Each 1 bit in the mask enables the core to accept work from
  1511. * the corresponding group.
  1512. */
  1513. static inline void cvmx_pow_set_group_mask(uint64_t core_num, uint64_t mask)
  1514. {
  1515. union cvmx_pow_pp_grp_mskx grp_msk;
  1516. grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num));
  1517. grp_msk.s.grp_msk = mask;
  1518. cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
  1519. }
  1520. /**
  1521. * This function sets POW static priorities for a core. Each input queue has
  1522. * an associated priority value.
  1523. *
  1524. * @core_num: core to apply priorities to
  1525. * @priority: Vector of 8 priorities, one per POW Input Queue (0-7).
  1526. * Highest priority is 0 and lowest is 7. A priority value
  1527. * of 0xF instructs POW to skip the Input Queue when
  1528. * scheduling to this specific core.
  1529. * NOTE: priorities should not have gaps in values, meaning
  1530. * {0,1,1,1,1,1,1,1} is a valid configuration while
  1531. * {0,2,2,2,2,2,2,2} is not.
  1532. */
  1533. static inline void cvmx_pow_set_priority(uint64_t core_num,
  1534. const uint8_t priority[])
  1535. {
  1536. /* POW priorities are supported on CN5xxx and later */
  1537. if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
  1538. union cvmx_pow_pp_grp_mskx grp_msk;
  1539. grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num));
  1540. grp_msk.s.qos0_pri = priority[0];
  1541. grp_msk.s.qos1_pri = priority[1];
  1542. grp_msk.s.qos2_pri = priority[2];
  1543. grp_msk.s.qos3_pri = priority[3];
  1544. grp_msk.s.qos4_pri = priority[4];
  1545. grp_msk.s.qos5_pri = priority[5];
  1546. grp_msk.s.qos6_pri = priority[6];
  1547. grp_msk.s.qos7_pri = priority[7];
  1548. /* Detect gaps between priorities and flag error */
  1549. {
  1550. int i;
  1551. uint32_t prio_mask = 0;
  1552. for (i = 0; i < 8; i++)
  1553. if (priority[i] != 0xF)
  1554. prio_mask |= 1 << priority[i];
  1555. if (prio_mask ^ ((1 << cvmx_pop(prio_mask)) - 1)) {
  1556. pr_err("POW static priorities should be "
  1557. "contiguous (0x%llx)\n",
  1558. (unsigned long long)prio_mask);
  1559. return;
  1560. }
  1561. }
  1562. cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
  1563. }
  1564. }
  1565. /**
  1566. * Performs a tag switch and then an immediate deschedule. This completes
  1567. * immediately, so completion must not be waited for. This function does NOT
  1568. * update the wqe in DRAM to match arguments.
  1569. *
  1570. * This function does NOT wait for any prior tag switches to complete, so the
  1571. * calling code must do this.
  1572. *
  1573. * Note the following CAVEAT of the Octeon HW behavior when
  1574. * re-scheduling DE-SCHEDULEd items whose (next) state is
  1575. * ORDERED:
  1576. * - If there are no switches pending at the time that the
  1577. * HW executes the de-schedule, the HW will only re-schedule
  1578. * the head of the FIFO associated with the given tag. This
  1579. * means that in many respects, the HW treats this ORDERED
  1580. * tag as an ATOMIC tag. Note that in the SWTAG_DESCH
  1581. * case (to an ORDERED tag), the HW will do the switch
  1582. * before the deschedule whenever it is possible to do
  1583. * the switch immediately, so it may often look like
  1584. * this case.
  1585. * - If there is a pending switch to ORDERED at the time
  1586. * the HW executes the de-schedule, the HW will perform
  1587. * the switch at the time it re-schedules, and will be
  1588. * able to reschedule any/all of the entries with the
  1589. * same tag.
  1590. * Due to this behavior, the RECOMMENDATION to software is
  1591. * that they have a (next) state of ATOMIC when they
  1592. * DE-SCHEDULE. If an ORDERED tag is what was really desired,
  1593. * SW can choose to immediately switch to an ORDERED tag
  1594. * after the work (that has an ATOMIC tag) is re-scheduled.
  1595. * Note that since there are never any tag switches pending
  1596. * when the HW re-schedules, this switch can be IMMEDIATE upon
  1597. * the reception of the pointer during the re-schedule.
  1598. *
  1599. * @tag: New tag value
  1600. * @tag_type: New tag type
  1601. * @group: New group value
  1602. * @no_sched: Control whether this work queue entry will be rescheduled.
  1603. * - 1 : don't schedule this work
  1604. * - 0 : allow this work to be scheduled.
  1605. */
  1606. static inline void cvmx_pow_tag_sw_desched_nocheck(
  1607. uint32_t tag,
  1608. enum cvmx_pow_tag_type tag_type,
  1609. uint64_t group,
  1610. uint64_t no_sched)
  1611. {
  1612. cvmx_addr_t ptr;
  1613. cvmx_pow_tag_req_t tag_req;
  1614. if (CVMX_ENABLE_POW_CHECKS) {
  1615. cvmx_pow_tag_req_t current_tag;
  1616. __cvmx_pow_warn_if_pending_switch(__func__);
  1617. current_tag = cvmx_pow_get_current_tag();
  1618. if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
  1619. pr_warning("%s called with NULL_NULL tag\n",
  1620. __func__);
  1621. if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
  1622. pr_warning("%s called with NULL tag. Deschedule not "
  1623. "allowed from NULL state\n",
  1624. __func__);
  1625. if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC)
  1626. && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC))
  1627. pr_warning("%s called where neither the before or "
  1628. "after tag is ATOMIC\n",
  1629. __func__);
  1630. }
  1631. tag_req.u64 = 0;
  1632. tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_DESCH;
  1633. tag_req.s.tag = tag;
  1634. tag_req.s.type = tag_type;
  1635. tag_req.s.grp = group;
  1636. tag_req.s.no_sched = no_sched;
  1637. ptr.u64 = 0;
  1638. ptr.sio.mem_region = CVMX_IO_SEG;
  1639. ptr.sio.is_io = 1;
  1640. ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
  1641. /*
  1642. * since TAG3 is used, this store will clear the local pending
  1643. * switch bit.
  1644. */
  1645. cvmx_write_io(ptr.u64, tag_req.u64);
  1646. }
  1647. /**
  1648. * Performs a tag switch and then an immediate deschedule. This completes
  1649. * immediately, so completion must not be waited for. This function does NOT
  1650. * update the wqe in DRAM to match arguments.
  1651. *
  1652. * This function waits for any prior tag switches to complete, so the
  1653. * calling code may call this function with a pending tag switch.
  1654. *
  1655. * Note the following CAVEAT of the Octeon HW behavior when
  1656. * re-scheduling DE-SCHEDULEd items whose (next) state is
  1657. * ORDERED:
  1658. * - If there are no switches pending at the time that the
  1659. * HW executes the de-schedule, the HW will only re-schedule
  1660. * the head of the FIFO associated with the given tag. This
  1661. * means that in many respects, the HW treats this ORDERED
  1662. * tag as an ATOMIC tag. Note that in the SWTAG_DESCH
  1663. * case (to an ORDERED tag), the HW will do the switch
  1664. * before the deschedule whenever it is possible to do
  1665. * the switch immediately, so it may often look like
  1666. * this case.
  1667. * - If there is a pending switch to ORDERED at the time
  1668. * the HW executes the de-schedule, the HW will perform
  1669. * the switch at the time it re-schedules, and will be
  1670. * able to reschedule any/all of the entries with the
  1671. * same tag.
  1672. * Due to this behavior, the RECOMMENDATION to software is
  1673. * that they have a (next) state of ATOMIC when they
  1674. * DE-SCHEDULE. If an ORDERED tag is what was really desired,
  1675. * SW can choose to immediately switch to an ORDERED tag
  1676. * after the work (that has an ATOMIC tag) is re-scheduled.
  1677. * Note that since there are never any tag switches pending
  1678. * when the HW re-schedules, this switch can be IMMEDIATE upon
  1679. * the reception of the pointer during the re-schedule.
  1680. *
  1681. * @tag: New tag value
  1682. * @tag_type: New tag type
  1683. * @group: New group value
  1684. * @no_sched: Control whether this work queue entry will be rescheduled.
  1685. * - 1 : don't schedule this work
  1686. * - 0 : allow this work to be scheduled.
  1687. */
  1688. static inline void cvmx_pow_tag_sw_desched(uint32_t tag,
  1689. enum cvmx_pow_tag_type tag_type,
  1690. uint64_t group, uint64_t no_sched)
  1691. {
  1692. if (CVMX_ENABLE_POW_CHECKS)
  1693. __cvmx_pow_warn_if_pending_switch(__func__);
  1694. /* Need to make sure any writes to the work queue entry are complete */
  1695. CVMX_SYNCWS;
  1696. /*
  1697. * Ensure that there is not a pending tag switch, as a tag
  1698. * switch cannot be started if a previous switch is still
  1699. * pending.
  1700. */
  1701. cvmx_pow_tag_sw_wait();
  1702. cvmx_pow_tag_sw_desched_nocheck(tag, tag_type, group, no_sched);
  1703. }
  1704. /**
  1705. * Descchedules the current work queue entry.
  1706. *
  1707. * @no_sched: no schedule flag value to be set on the work queue
  1708. * entry. If this is set the entry will not be
  1709. * rescheduled.
  1710. */
  1711. static inline void cvmx_pow_desched(uint64_t no_sched)
  1712. {
  1713. cvmx_addr_t ptr;
  1714. cvmx_pow_tag_req_t tag_req;
  1715. if (CVMX_ENABLE_POW_CHECKS) {
  1716. cvmx_pow_tag_req_t current_tag;
  1717. __cvmx_pow_warn_if_pending_switch(__func__);
  1718. current_tag = cvmx_pow_get_current_tag();
  1719. if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
  1720. pr_warning("%s called with NULL_NULL tag\n",
  1721. __func__);
  1722. if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
  1723. pr_warning("%s called with NULL tag. Deschedule not "
  1724. "expected from NULL state\n",
  1725. __func__);
  1726. }
  1727. /* Need to make sure any writes to the work queue entry are complete */
  1728. CVMX_SYNCWS;
  1729. tag_req.u64 = 0;
  1730. tag_req.s.op = CVMX_POW_TAG_OP_DESCH;
  1731. tag_req.s.no_sched = no_sched;
  1732. ptr.u64 = 0;
  1733. ptr.sio.mem_region = CVMX_IO_SEG;
  1734. ptr.sio.is_io = 1;
  1735. ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
  1736. /*
  1737. * since TAG3 is used, this store will clear the local pending
  1738. * switch bit.
  1739. */
  1740. cvmx_write_io(ptr.u64, tag_req.u64);
  1741. }
  1742. /****************************************************
  1743. * Define usage of bits within the 32 bit tag values.
  1744. *****************************************************/
  1745. /*
  1746. * Number of bits of the tag used by software. The SW bits are always
  1747. * a contiguous block of the high starting at bit 31. The hardware
  1748. * bits are always the low bits. By default, the top 8 bits of the
  1749. * tag are reserved for software, and the low 24 are set by the IPD
  1750. * unit.
  1751. */
  1752. #define CVMX_TAG_SW_BITS (8)
  1753. #define CVMX_TAG_SW_SHIFT (32 - CVMX_TAG_SW_BITS)
  1754. /* Below is the list of values for the top 8 bits of the tag. */
  1755. /*
  1756. * Tag values with top byte of this value are reserved for internal
  1757. * executive uses.
  1758. */
  1759. #define CVMX_TAG_SW_BITS_INTERNAL 0x1
  1760. /* The executive divides the remaining 24 bits as follows:
  1761. * - the upper 8 bits (bits 23 - 16 of the tag) define a subgroup
  1762. *
  1763. * - the lower 16 bits (bits 15 - 0 of the tag) define are the value
  1764. * with the subgroup
  1765. *
  1766. * Note that this section describes the format of tags generated by
  1767. * software - refer to the hardware documentation for a description of
  1768. * the tags values generated by the packet input hardware. Subgroups
  1769. * are defined here.
  1770. */
  1771. /* Mask for the value portion of the tag */
  1772. #define CVMX_TAG_SUBGROUP_MASK 0xFFFF
  1773. #define CVMX_TAG_SUBGROUP_SHIFT 16
  1774. #define CVMX_TAG_SUBGROUP_PKO 0x1
  1775. /* End of executive tag subgroup definitions */
  1776. /*
  1777. * The remaining values software bit values 0x2 - 0xff are available
  1778. * for application use.
  1779. */
  1780. /**
  1781. * This function creates a 32 bit tag value from the two values provided.
  1782. *
  1783. * @sw_bits: The upper bits (number depends on configuration) are set
  1784. * to this value. The remainder of bits are set by the
  1785. * hw_bits parameter.
  1786. *
  1787. * @hw_bits: The lower bits (number depends on configuration) are set
  1788. * to this value. The remainder of bits are set by the
  1789. * sw_bits parameter.
  1790. *
  1791. * Returns 32 bit value of the combined hw and sw bits.
  1792. */
  1793. static inline uint32_t cvmx_pow_tag_compose(uint64_t sw_bits, uint64_t hw_bits)
  1794. {
  1795. return ((sw_bits & cvmx_build_mask(CVMX_TAG_SW_BITS)) <<
  1796. CVMX_TAG_SW_SHIFT) |
  1797. (hw_bits & cvmx_build_mask(32 - CVMX_TAG_SW_BITS));
  1798. }
  1799. /**
  1800. * Extracts the bits allocated for software use from the tag
  1801. *
  1802. * @tag: 32 bit tag value
  1803. *
  1804. * Returns N bit software tag value, where N is configurable with the
  1805. * CVMX_TAG_SW_BITS define
  1806. */
  1807. static inline uint32_t cvmx_pow_tag_get_sw_bits(uint64_t tag)
  1808. {
  1809. return (tag >> (32 - CVMX_TAG_SW_BITS)) &
  1810. cvmx_build_mask(CVMX_TAG_SW_BITS);
  1811. }
  1812. /**
  1813. *
  1814. * Extracts the bits allocated for hardware use from the tag
  1815. *
  1816. * @tag: 32 bit tag value
  1817. *
  1818. * Returns (32 - N) bit software tag value, where N is configurable
  1819. * with the CVMX_TAG_SW_BITS define
  1820. */
  1821. static inline uint32_t cvmx_pow_tag_get_hw_bits(uint64_t tag)
  1822. {
  1823. return tag & cvmx_build_mask(32 - CVMX_TAG_SW_BITS);
  1824. }
  1825. /**
  1826. * Store the current POW internal state into the supplied
  1827. * buffer. It is recommended that you pass a buffer of at least
  1828. * 128KB. The format of the capture may change based on SDK
  1829. * version and Octeon chip.
  1830. *
  1831. * @buffer: Buffer to store capture into
  1832. * @buffer_size:
  1833. * The size of the supplied buffer
  1834. *
  1835. * Returns Zero on success, negative on failure
  1836. */
  1837. extern int cvmx_pow_capture(void *buffer, int buffer_size);
  1838. /**
  1839. * Dump a POW capture to the console in a human readable format.
  1840. *
  1841. * @buffer: POW capture from cvmx_pow_capture()
  1842. * @buffer_size:
  1843. * Size of the buffer
  1844. */
  1845. extern void cvmx_pow_display(void *buffer, int buffer_size);
  1846. /**
  1847. * Return the number of POW entries supported by this chip
  1848. *
  1849. * Returns Number of POW entries
  1850. */
  1851. extern int cvmx_pow_get_num_entries(void);
  1852. #endif /* __CVMX_POW_H__ */