ti_sci.c 90 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Texas Instruments System Control Interface Protocol Driver
  4. * Based on drivers/firmware/ti_sci.c from Linux.
  5. *
  6. * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
  7. * Lokesh Vutla <lokeshvutla@ti.com>
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <errno.h>
  12. #include <log.h>
  13. #include <mailbox.h>
  14. #include <malloc.h>
  15. #include <dm/device.h>
  16. #include <dm/device_compat.h>
  17. #include <dm/devres.h>
  18. #include <linux/bitops.h>
  19. #include <linux/compat.h>
  20. #include <linux/err.h>
  21. #include <linux/soc/ti/k3-sec-proxy.h>
  22. #include <linux/soc/ti/ti_sci_protocol.h>
  23. #include "ti_sci.h"
  24. #include "ti_sci_static_data.h"
  25. /* List of all TI SCI devices active in system */
  26. static LIST_HEAD(ti_sci_list);
  27. /**
  28. * struct ti_sci_xfer - Structure representing a message flow
  29. * @tx_message: Transmit message
  30. * @rx_len: Receive message length
  31. */
  32. struct ti_sci_xfer {
  33. struct k3_sec_proxy_msg tx_message;
  34. u8 rx_len;
  35. };
  36. /**
  37. * struct ti_sci_rm_type_map - Structure representing TISCI Resource
  38. * management representation of dev_ids.
  39. * @dev_id: TISCI device ID
  40. * @type: Corresponding id as identified by TISCI RM.
  41. *
  42. * Note: This is used only as a work around for using RM range apis
  43. * for AM654 SoC. For future SoCs dev_id will be used as type
  44. * for RM range APIs. In order to maintain ABI backward compatibility
  45. * type is not being changed for AM654 SoC.
  46. */
  47. struct ti_sci_rm_type_map {
  48. u32 dev_id;
  49. u16 type;
  50. };
  51. /**
  52. * struct ti_sci_desc - Description of SoC integration
  53. * @default_host_id: Host identifier representing the compute entity
  54. * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
  55. * @max_msgs: Maximum number of messages that can be pending
  56. * simultaneously in the system
  57. * @max_msg_size: Maximum size of data per message that can be handled.
  58. */
  59. struct ti_sci_desc {
  60. u8 default_host_id;
  61. int max_rx_timeout_ms;
  62. int max_msgs;
  63. int max_msg_size;
  64. };
  65. /**
  66. * struct ti_sci_info - Structure representing a TI SCI instance
  67. * @dev: Device pointer
  68. * @desc: SoC description for this instance
  69. * @handle: Instance of TI SCI handle to send to clients.
  70. * @chan_tx: Transmit mailbox channel
  71. * @chan_rx: Receive mailbox channel
  72. * @xfer: xfer info
  73. * @list: list head
  74. * @is_secure: Determines if the communication is through secure threads.
  75. * @host_id: Host identifier representing the compute entity
  76. * @seq: Seq id used for verification for tx and rx message.
  77. */
  78. struct ti_sci_info {
  79. struct udevice *dev;
  80. const struct ti_sci_desc *desc;
  81. struct ti_sci_handle handle;
  82. struct mbox_chan chan_tx;
  83. struct mbox_chan chan_rx;
  84. struct mbox_chan chan_notify;
  85. struct ti_sci_xfer xfer;
  86. struct list_head list;
  87. struct list_head dev_list;
  88. bool is_secure;
  89. u8 host_id;
  90. u8 seq;
  91. };
  92. struct ti_sci_exclusive_dev {
  93. u32 id;
  94. u32 count;
  95. struct list_head list;
  96. };
  97. #define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle)
  98. /**
  99. * ti_sci_setup_one_xfer() - Setup one message type
  100. * @info: Pointer to SCI entity information
  101. * @msg_type: Message type
  102. * @msg_flags: Flag to set for the message
  103. * @buf: Buffer to be send to mailbox channel
  104. * @tx_message_size: transmit message size
  105. * @rx_message_size: receive message size. may be set to zero for send-only
  106. * transactions.
  107. *
  108. * Helper function which is used by various command functions that are
  109. * exposed to clients of this driver for allocating a message traffic event.
  110. *
  111. * Return: Corresponding ti_sci_xfer pointer if all went fine,
  112. * else appropriate error pointer.
  113. */
  114. static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info,
  115. u16 msg_type, u32 msg_flags,
  116. u32 *buf,
  117. size_t tx_message_size,
  118. size_t rx_message_size)
  119. {
  120. struct ti_sci_xfer *xfer = &info->xfer;
  121. struct ti_sci_msg_hdr *hdr;
  122. /* Ensure we have sane transfer sizes */
  123. if (rx_message_size > info->desc->max_msg_size ||
  124. tx_message_size > info->desc->max_msg_size ||
  125. (rx_message_size > 0 && rx_message_size < sizeof(*hdr)) ||
  126. tx_message_size < sizeof(*hdr))
  127. return ERR_PTR(-ERANGE);
  128. info->seq = ~info->seq;
  129. xfer->tx_message.buf = buf;
  130. xfer->tx_message.len = tx_message_size;
  131. xfer->rx_len = (u8)rx_message_size;
  132. hdr = (struct ti_sci_msg_hdr *)buf;
  133. hdr->seq = info->seq;
  134. hdr->type = msg_type;
  135. hdr->host = info->host_id;
  136. hdr->flags = msg_flags;
  137. return xfer;
  138. }
  139. /**
  140. * ti_sci_get_response() - Receive response from mailbox channel
  141. * @info: Pointer to SCI entity information
  142. * @xfer: Transfer to initiate and wait for response
  143. * @chan: Channel to receive the response
  144. *
  145. * Return: -ETIMEDOUT in case of no response, if transmit error,
  146. * return corresponding error, else if all goes well,
  147. * return 0.
  148. */
  149. static inline int ti_sci_get_response(struct ti_sci_info *info,
  150. struct ti_sci_xfer *xfer,
  151. struct mbox_chan *chan)
  152. {
  153. struct k3_sec_proxy_msg *msg = &xfer->tx_message;
  154. struct ti_sci_secure_msg_hdr *secure_hdr;
  155. struct ti_sci_msg_hdr *hdr;
  156. int ret;
  157. /* Receive the response */
  158. ret = mbox_recv(chan, msg, info->desc->max_rx_timeout_ms * 1000);
  159. if (ret) {
  160. dev_err(info->dev, "%s: Message receive failed. ret = %d\n",
  161. __func__, ret);
  162. return ret;
  163. }
  164. /* ToDo: Verify checksum */
  165. if (info->is_secure) {
  166. secure_hdr = (struct ti_sci_secure_msg_hdr *)msg->buf;
  167. msg->buf = (u32 *)((void *)msg->buf + sizeof(*secure_hdr));
  168. }
  169. /* msg is updated by mailbox driver */
  170. hdr = (struct ti_sci_msg_hdr *)msg->buf;
  171. /* Sanity check for message response */
  172. if (hdr->seq != info->seq) {
  173. dev_dbg(info->dev, "%s: Message for %d is not expected\n",
  174. __func__, hdr->seq);
  175. return ret;
  176. }
  177. if (msg->len > info->desc->max_msg_size) {
  178. dev_err(info->dev, "%s: Unable to handle %zu xfer (max %d)\n",
  179. __func__, msg->len, info->desc->max_msg_size);
  180. return -EINVAL;
  181. }
  182. if (msg->len < xfer->rx_len) {
  183. dev_err(info->dev, "%s: Recv xfer %zu < expected %d length\n",
  184. __func__, msg->len, xfer->rx_len);
  185. }
  186. return ret;
  187. }
  188. /**
  189. * ti_sci_do_xfer() - Do one transfer
  190. * @info: Pointer to SCI entity information
  191. * @xfer: Transfer to initiate and wait for response
  192. *
  193. * Return: 0 if all went fine, else return appropriate error.
  194. */
  195. static inline int ti_sci_do_xfer(struct ti_sci_info *info,
  196. struct ti_sci_xfer *xfer)
  197. {
  198. struct k3_sec_proxy_msg *msg = &xfer->tx_message;
  199. u8 secure_buf[info->desc->max_msg_size];
  200. struct ti_sci_secure_msg_hdr secure_hdr;
  201. int ret;
  202. if (info->is_secure) {
  203. /* ToDo: get checksum of the entire message */
  204. secure_hdr.checksum = 0;
  205. secure_hdr.reserved = 0;
  206. memcpy(&secure_buf[sizeof(secure_hdr)], xfer->tx_message.buf,
  207. xfer->tx_message.len);
  208. xfer->tx_message.buf = (u32 *)secure_buf;
  209. xfer->tx_message.len += sizeof(secure_hdr);
  210. if (xfer->rx_len)
  211. xfer->rx_len += sizeof(secure_hdr);
  212. }
  213. /* Send the message */
  214. ret = mbox_send(&info->chan_tx, msg);
  215. if (ret) {
  216. dev_err(info->dev, "%s: Message sending failed. ret = %d\n",
  217. __func__, ret);
  218. return ret;
  219. }
  220. /* Get response if requested */
  221. if (xfer->rx_len)
  222. ret = ti_sci_get_response(info, xfer, &info->chan_rx);
  223. return ret;
  224. }
  225. /**
  226. * ti_sci_cmd_get_revision() - command to get the revision of the SCI entity
  227. * @handle: pointer to TI SCI handle
  228. *
  229. * Updates the SCI information in the internal data structure.
  230. *
  231. * Return: 0 if all went fine, else return appropriate error.
  232. */
  233. static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle)
  234. {
  235. struct ti_sci_msg_resp_version *rev_info;
  236. struct ti_sci_version_info *ver;
  237. struct ti_sci_msg_hdr hdr;
  238. struct ti_sci_info *info;
  239. struct ti_sci_xfer *xfer;
  240. int ret;
  241. if (IS_ERR(handle))
  242. return PTR_ERR(handle);
  243. if (!handle)
  244. return -EINVAL;
  245. info = handle_to_ti_sci_info(handle);
  246. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_VERSION,
  247. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  248. (u32 *)&hdr, sizeof(struct ti_sci_msg_hdr),
  249. sizeof(*rev_info));
  250. if (IS_ERR(xfer)) {
  251. ret = PTR_ERR(xfer);
  252. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  253. return ret;
  254. }
  255. ret = ti_sci_do_xfer(info, xfer);
  256. if (ret) {
  257. dev_err(info->dev, "Mbox communication fail %d\n", ret);
  258. return ret;
  259. }
  260. rev_info = (struct ti_sci_msg_resp_version *)xfer->tx_message.buf;
  261. ver = &handle->version;
  262. ver->abi_major = rev_info->abi_major;
  263. ver->abi_minor = rev_info->abi_minor;
  264. ver->firmware_revision = rev_info->firmware_revision;
  265. strncpy(ver->firmware_description, rev_info->firmware_description,
  266. sizeof(ver->firmware_description));
  267. return 0;
  268. }
  269. /**
  270. * ti_sci_is_response_ack() - Generic ACK/NACK message checkup
  271. * @r: pointer to response buffer
  272. *
  273. * Return: true if the response was an ACK, else returns false.
  274. */
  275. static inline bool ti_sci_is_response_ack(void *r)
  276. {
  277. struct ti_sci_msg_hdr *hdr = r;
  278. return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
  279. }
  280. /**
  281. * cmd_set_board_config_using_msg() - Common command to send board configuration
  282. * message
  283. * @handle: pointer to TI SCI handle
  284. * @msg_type: One of the TISCI message types to set board configuration
  285. * @addr: Address where the board config structure is located
  286. * @size: Size of the board config structure
  287. *
  288. * Return: 0 if all went well, else returns appropriate error value.
  289. */
  290. static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle,
  291. u16 msg_type, u64 addr, u32 size)
  292. {
  293. struct ti_sci_msg_board_config req;
  294. struct ti_sci_msg_hdr *resp;
  295. struct ti_sci_info *info;
  296. struct ti_sci_xfer *xfer;
  297. int ret = 0;
  298. if (IS_ERR(handle))
  299. return PTR_ERR(handle);
  300. if (!handle)
  301. return -EINVAL;
  302. info = handle_to_ti_sci_info(handle);
  303. xfer = ti_sci_setup_one_xfer(info, msg_type,
  304. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  305. (u32 *)&req, sizeof(req), sizeof(*resp));
  306. if (IS_ERR(xfer)) {
  307. ret = PTR_ERR(xfer);
  308. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  309. return ret;
  310. }
  311. req.boardcfgp_high = (addr >> 32) & 0xffffffff;
  312. req.boardcfgp_low = addr & 0xffffffff;
  313. req.boardcfg_size = size;
  314. ret = ti_sci_do_xfer(info, xfer);
  315. if (ret) {
  316. dev_err(info->dev, "Mbox send fail %d\n", ret);
  317. return ret;
  318. }
  319. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  320. if (!ti_sci_is_response_ack(resp))
  321. return -ENODEV;
  322. return ret;
  323. }
  324. /**
  325. * ti_sci_cmd_set_board_config() - Command to send board configuration message
  326. * @handle: pointer to TI SCI handle
  327. * @addr: Address where the board config structure is located
  328. * @size: Size of the board config structure
  329. *
  330. * Return: 0 if all went well, else returns appropriate error value.
  331. */
  332. static int ti_sci_cmd_set_board_config(const struct ti_sci_handle *handle,
  333. u64 addr, u32 size)
  334. {
  335. return cmd_set_board_config_using_msg(handle,
  336. TI_SCI_MSG_BOARD_CONFIG,
  337. addr, size);
  338. }
  339. /**
  340. * ti_sci_cmd_set_board_config_rm() - Command to send board resource
  341. * management configuration
  342. * @handle: pointer to TI SCI handle
  343. * @addr: Address where the board RM config structure is located
  344. * @size: Size of the RM config structure
  345. *
  346. * Return: 0 if all went well, else returns appropriate error value.
  347. */
  348. static
  349. int ti_sci_cmd_set_board_config_rm(const struct ti_sci_handle *handle,
  350. u64 addr, u32 size)
  351. {
  352. return cmd_set_board_config_using_msg(handle,
  353. TI_SCI_MSG_BOARD_CONFIG_RM,
  354. addr, size);
  355. }
  356. /**
  357. * ti_sci_cmd_set_board_config_security() - Command to send board security
  358. * configuration message
  359. * @handle: pointer to TI SCI handle
  360. * @addr: Address where the board security config structure is located
  361. * @size: Size of the security config structure
  362. *
  363. * Return: 0 if all went well, else returns appropriate error value.
  364. */
  365. static
  366. int ti_sci_cmd_set_board_config_security(const struct ti_sci_handle *handle,
  367. u64 addr, u32 size)
  368. {
  369. return cmd_set_board_config_using_msg(handle,
  370. TI_SCI_MSG_BOARD_CONFIG_SECURITY,
  371. addr, size);
  372. }
  373. /**
  374. * ti_sci_cmd_set_board_config_pm() - Command to send board power and clock
  375. * configuration message
  376. * @handle: pointer to TI SCI handle
  377. * @addr: Address where the board PM config structure is located
  378. * @size: Size of the PM config structure
  379. *
  380. * Return: 0 if all went well, else returns appropriate error value.
  381. */
  382. static int ti_sci_cmd_set_board_config_pm(const struct ti_sci_handle *handle,
  383. u64 addr, u32 size)
  384. {
  385. return cmd_set_board_config_using_msg(handle,
  386. TI_SCI_MSG_BOARD_CONFIG_PM,
  387. addr, size);
  388. }
  389. static struct ti_sci_exclusive_dev
  390. *ti_sci_get_exclusive_dev(struct list_head *dev_list, u32 id)
  391. {
  392. struct ti_sci_exclusive_dev *dev;
  393. list_for_each_entry(dev, dev_list, list)
  394. if (dev->id == id)
  395. return dev;
  396. return NULL;
  397. }
  398. static void ti_sci_add_exclusive_dev(struct ti_sci_info *info, u32 id)
  399. {
  400. struct ti_sci_exclusive_dev *dev;
  401. dev = ti_sci_get_exclusive_dev(&info->dev_list, id);
  402. if (dev) {
  403. dev->count++;
  404. return;
  405. }
  406. dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  407. dev->id = id;
  408. dev->count = 1;
  409. INIT_LIST_HEAD(&dev->list);
  410. list_add_tail(&dev->list, &info->dev_list);
  411. }
  412. static void ti_sci_delete_exclusive_dev(struct ti_sci_info *info, u32 id)
  413. {
  414. struct ti_sci_exclusive_dev *dev;
  415. dev = ti_sci_get_exclusive_dev(&info->dev_list, id);
  416. if (!dev)
  417. return;
  418. if (dev->count > 0)
  419. dev->count--;
  420. }
  421. /**
  422. * ti_sci_set_device_state() - Set device state helper
  423. * @handle: pointer to TI SCI handle
  424. * @id: Device identifier
  425. * @flags: flags to setup for the device
  426. * @state: State to move the device to
  427. *
  428. * Return: 0 if all went well, else returns appropriate error value.
  429. */
  430. static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
  431. u32 id, u32 flags, u8 state)
  432. {
  433. struct ti_sci_msg_req_set_device_state req;
  434. struct ti_sci_msg_hdr *resp;
  435. struct ti_sci_info *info;
  436. struct ti_sci_xfer *xfer;
  437. int ret = 0;
  438. if (IS_ERR(handle))
  439. return PTR_ERR(handle);
  440. if (!handle)
  441. return -EINVAL;
  442. info = handle_to_ti_sci_info(handle);
  443. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
  444. flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  445. (u32 *)&req, sizeof(req), sizeof(*resp));
  446. if (IS_ERR(xfer)) {
  447. ret = PTR_ERR(xfer);
  448. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  449. return ret;
  450. }
  451. req.id = id;
  452. req.state = state;
  453. ret = ti_sci_do_xfer(info, xfer);
  454. if (ret) {
  455. dev_err(info->dev, "Mbox send fail %d\n", ret);
  456. return ret;
  457. }
  458. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  459. if (!ti_sci_is_response_ack(resp))
  460. return -ENODEV;
  461. if (state == MSG_DEVICE_SW_STATE_AUTO_OFF)
  462. ti_sci_delete_exclusive_dev(info, id);
  463. else if (flags & MSG_FLAG_DEVICE_EXCLUSIVE)
  464. ti_sci_add_exclusive_dev(info, id);
  465. return ret;
  466. }
  467. /**
  468. * ti_sci_set_device_state_no_wait() - Set device state helper without
  469. * requesting or waiting for a response.
  470. * @handle: pointer to TI SCI handle
  471. * @id: Device identifier
  472. * @flags: flags to setup for the device
  473. * @state: State to move the device to
  474. *
  475. * Return: 0 if all went well, else returns appropriate error value.
  476. */
  477. static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle,
  478. u32 id, u32 flags, u8 state)
  479. {
  480. struct ti_sci_msg_req_set_device_state req;
  481. struct ti_sci_info *info;
  482. struct ti_sci_xfer *xfer;
  483. int ret = 0;
  484. if (IS_ERR(handle))
  485. return PTR_ERR(handle);
  486. if (!handle)
  487. return -EINVAL;
  488. info = handle_to_ti_sci_info(handle);
  489. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
  490. flags | TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
  491. (u32 *)&req, sizeof(req), 0);
  492. if (IS_ERR(xfer)) {
  493. ret = PTR_ERR(xfer);
  494. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  495. return ret;
  496. }
  497. req.id = id;
  498. req.state = state;
  499. ret = ti_sci_do_xfer(info, xfer);
  500. if (ret)
  501. dev_err(info->dev, "Mbox send fail %d\n", ret);
  502. return ret;
  503. }
  504. /**
  505. * ti_sci_get_device_state() - Get device state helper
  506. * @handle: Handle to the device
  507. * @id: Device Identifier
  508. * @clcnt: Pointer to Context Loss Count
  509. * @resets: pointer to resets
  510. * @p_state: pointer to p_state
  511. * @c_state: pointer to c_state
  512. *
  513. * Return: 0 if all went fine, else return appropriate error.
  514. */
  515. static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
  516. u32 id, u32 *clcnt, u32 *resets,
  517. u8 *p_state, u8 *c_state)
  518. {
  519. struct ti_sci_msg_resp_get_device_state *resp;
  520. struct ti_sci_msg_req_get_device_state req;
  521. struct ti_sci_info *info;
  522. struct ti_sci_xfer *xfer;
  523. int ret = 0;
  524. if (IS_ERR(handle))
  525. return PTR_ERR(handle);
  526. if (!handle)
  527. return -EINVAL;
  528. if (!clcnt && !resets && !p_state && !c_state)
  529. return -EINVAL;
  530. info = handle_to_ti_sci_info(handle);
  531. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE,
  532. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  533. (u32 *)&req, sizeof(req), sizeof(*resp));
  534. if (IS_ERR(xfer)) {
  535. ret = PTR_ERR(xfer);
  536. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  537. return ret;
  538. }
  539. req.id = id;
  540. ret = ti_sci_do_xfer(info, xfer);
  541. if (ret) {
  542. dev_err(info->dev, "Mbox send fail %d\n", ret);
  543. return ret;
  544. }
  545. resp = (struct ti_sci_msg_resp_get_device_state *)xfer->tx_message.buf;
  546. if (!ti_sci_is_response_ack(resp))
  547. return -ENODEV;
  548. if (clcnt)
  549. *clcnt = resp->context_loss_count;
  550. if (resets)
  551. *resets = resp->resets;
  552. if (p_state)
  553. *p_state = resp->programmed_state;
  554. if (c_state)
  555. *c_state = resp->current_state;
  556. return ret;
  557. }
  558. /**
  559. * ti_sci_cmd_get_device() - command to request for device managed by TISCI
  560. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  561. * @id: Device Identifier
  562. *
  563. * Request for the device - NOTE: the client MUST maintain integrity of
  564. * usage count by balancing get_device with put_device. No refcounting is
  565. * managed by driver for that purpose.
  566. *
  567. * NOTE: The request is for exclusive access for the processor.
  568. *
  569. * Return: 0 if all went fine, else return appropriate error.
  570. */
  571. static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id)
  572. {
  573. return ti_sci_set_device_state(handle, id, 0,
  574. MSG_DEVICE_SW_STATE_ON);
  575. }
  576. static int ti_sci_cmd_get_device_exclusive(const struct ti_sci_handle *handle,
  577. u32 id)
  578. {
  579. return ti_sci_set_device_state(handle, id, MSG_FLAG_DEVICE_EXCLUSIVE,
  580. MSG_DEVICE_SW_STATE_ON);
  581. }
  582. /**
  583. * ti_sci_cmd_idle_device() - Command to idle a device managed by TISCI
  584. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  585. * @id: Device Identifier
  586. *
  587. * Request for the device - NOTE: the client MUST maintain integrity of
  588. * usage count by balancing get_device with put_device. No refcounting is
  589. * managed by driver for that purpose.
  590. *
  591. * Return: 0 if all went fine, else return appropriate error.
  592. */
  593. static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id)
  594. {
  595. return ti_sci_set_device_state(handle, id,
  596. 0,
  597. MSG_DEVICE_SW_STATE_RETENTION);
  598. }
  599. static int ti_sci_cmd_idle_device_exclusive(const struct ti_sci_handle *handle,
  600. u32 id)
  601. {
  602. return ti_sci_set_device_state(handle, id, MSG_FLAG_DEVICE_EXCLUSIVE,
  603. MSG_DEVICE_SW_STATE_RETENTION);
  604. }
  605. /**
  606. * ti_sci_cmd_put_device() - command to release a device managed by TISCI
  607. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  608. * @id: Device Identifier
  609. *
  610. * Request for the device - NOTE: the client MUST maintain integrity of
  611. * usage count by balancing get_device with put_device. No refcounting is
  612. * managed by driver for that purpose.
  613. *
  614. * Return: 0 if all went fine, else return appropriate error.
  615. */
  616. static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id)
  617. {
  618. return ti_sci_set_device_state(handle, id, 0,
  619. MSG_DEVICE_SW_STATE_AUTO_OFF);
  620. }
  621. static
  622. int ti_sci_cmd_release_exclusive_devices(const struct ti_sci_handle *handle)
  623. {
  624. struct ti_sci_exclusive_dev *dev, *tmp;
  625. struct ti_sci_info *info;
  626. int i, cnt;
  627. info = handle_to_ti_sci_info(handle);
  628. list_for_each_entry_safe(dev, tmp, &info->dev_list, list) {
  629. cnt = dev->count;
  630. debug("%s: id = %d, cnt = %d\n", __func__, dev->id, cnt);
  631. for (i = 0; i < cnt; i++)
  632. ti_sci_cmd_put_device(handle, dev->id);
  633. }
  634. return 0;
  635. }
  636. /**
  637. * ti_sci_cmd_dev_is_valid() - Is the device valid
  638. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  639. * @id: Device Identifier
  640. *
  641. * Return: 0 if all went fine and the device ID is valid, else return
  642. * appropriate error.
  643. */
  644. static int ti_sci_cmd_dev_is_valid(const struct ti_sci_handle *handle, u32 id)
  645. {
  646. u8 unused;
  647. /* check the device state which will also tell us if the ID is valid */
  648. return ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &unused);
  649. }
  650. /**
  651. * ti_sci_cmd_dev_get_clcnt() - Get context loss counter
  652. * @handle: Pointer to TISCI handle
  653. * @id: Device Identifier
  654. * @count: Pointer to Context Loss counter to populate
  655. *
  656. * Return: 0 if all went fine, else return appropriate error.
  657. */
  658. static int ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle *handle, u32 id,
  659. u32 *count)
  660. {
  661. return ti_sci_get_device_state(handle, id, count, NULL, NULL, NULL);
  662. }
  663. /**
  664. * ti_sci_cmd_dev_is_idle() - Check if the device is requested to be idle
  665. * @handle: Pointer to TISCI handle
  666. * @id: Device Identifier
  667. * @r_state: true if requested to be idle
  668. *
  669. * Return: 0 if all went fine, else return appropriate error.
  670. */
  671. static int ti_sci_cmd_dev_is_idle(const struct ti_sci_handle *handle, u32 id,
  672. bool *r_state)
  673. {
  674. int ret;
  675. u8 state;
  676. if (!r_state)
  677. return -EINVAL;
  678. ret = ti_sci_get_device_state(handle, id, NULL, NULL, &state, NULL);
  679. if (ret)
  680. return ret;
  681. *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION);
  682. return 0;
  683. }
  684. /**
  685. * ti_sci_cmd_dev_is_stop() - Check if the device is requested to be stopped
  686. * @handle: Pointer to TISCI handle
  687. * @id: Device Identifier
  688. * @r_state: true if requested to be stopped
  689. * @curr_state: true if currently stopped.
  690. *
  691. * Return: 0 if all went fine, else return appropriate error.
  692. */
  693. static int ti_sci_cmd_dev_is_stop(const struct ti_sci_handle *handle, u32 id,
  694. bool *r_state, bool *curr_state)
  695. {
  696. int ret;
  697. u8 p_state, c_state;
  698. if (!r_state && !curr_state)
  699. return -EINVAL;
  700. ret =
  701. ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
  702. if (ret)
  703. return ret;
  704. if (r_state)
  705. *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF);
  706. if (curr_state)
  707. *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF);
  708. return 0;
  709. }
  710. /**
  711. * ti_sci_cmd_dev_is_on() - Check if the device is requested to be ON
  712. * @handle: Pointer to TISCI handle
  713. * @id: Device Identifier
  714. * @r_state: true if requested to be ON
  715. * @curr_state: true if currently ON and active
  716. *
  717. * Return: 0 if all went fine, else return appropriate error.
  718. */
  719. static int ti_sci_cmd_dev_is_on(const struct ti_sci_handle *handle, u32 id,
  720. bool *r_state, bool *curr_state)
  721. {
  722. int ret;
  723. u8 p_state, c_state;
  724. if (!r_state && !curr_state)
  725. return -EINVAL;
  726. ret =
  727. ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
  728. if (ret)
  729. return ret;
  730. if (r_state)
  731. *r_state = (p_state == MSG_DEVICE_SW_STATE_ON);
  732. if (curr_state)
  733. *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON);
  734. return 0;
  735. }
  736. /**
  737. * ti_sci_cmd_dev_is_trans() - Check if the device is currently transitioning
  738. * @handle: Pointer to TISCI handle
  739. * @id: Device Identifier
  740. * @curr_state: true if currently transitioning.
  741. *
  742. * Return: 0 if all went fine, else return appropriate error.
  743. */
  744. static int ti_sci_cmd_dev_is_trans(const struct ti_sci_handle *handle, u32 id,
  745. bool *curr_state)
  746. {
  747. int ret;
  748. u8 state;
  749. if (!curr_state)
  750. return -EINVAL;
  751. ret = ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &state);
  752. if (ret)
  753. return ret;
  754. *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS);
  755. return 0;
  756. }
  757. /**
  758. * ti_sci_cmd_set_device_resets() - command to set resets for device managed
  759. * by TISCI
  760. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  761. * @id: Device Identifier
  762. * @reset_state: Device specific reset bit field
  763. *
  764. * Return: 0 if all went fine, else return appropriate error.
  765. */
  766. static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle,
  767. u32 id, u32 reset_state)
  768. {
  769. struct ti_sci_msg_req_set_device_resets req;
  770. struct ti_sci_msg_hdr *resp;
  771. struct ti_sci_info *info;
  772. struct ti_sci_xfer *xfer;
  773. int ret = 0;
  774. if (IS_ERR(handle))
  775. return PTR_ERR(handle);
  776. if (!handle)
  777. return -EINVAL;
  778. info = handle_to_ti_sci_info(handle);
  779. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_RESETS,
  780. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  781. (u32 *)&req, sizeof(req), sizeof(*resp));
  782. if (IS_ERR(xfer)) {
  783. ret = PTR_ERR(xfer);
  784. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  785. return ret;
  786. }
  787. req.id = id;
  788. req.resets = reset_state;
  789. ret = ti_sci_do_xfer(info, xfer);
  790. if (ret) {
  791. dev_err(info->dev, "Mbox send fail %d\n", ret);
  792. return ret;
  793. }
  794. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  795. if (!ti_sci_is_response_ack(resp))
  796. return -ENODEV;
  797. return ret;
  798. }
  799. /**
  800. * ti_sci_cmd_get_device_resets() - Get reset state for device managed
  801. * by TISCI
  802. * @handle: Pointer to TISCI handle
  803. * @id: Device Identifier
  804. * @reset_state: Pointer to reset state to populate
  805. *
  806. * Return: 0 if all went fine, else return appropriate error.
  807. */
  808. static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle,
  809. u32 id, u32 *reset_state)
  810. {
  811. return ti_sci_get_device_state(handle, id, NULL, reset_state, NULL,
  812. NULL);
  813. }
  814. /**
  815. * ti_sci_set_clock_state() - Set clock state helper
  816. * @handle: pointer to TI SCI handle
  817. * @dev_id: Device identifier this request is for
  818. * @clk_id: Clock identifier for the device for this request.
  819. * Each device has it's own set of clock inputs. This indexes
  820. * which clock input to modify.
  821. * @flags: Header flags as needed
  822. * @state: State to request for the clock.
  823. *
  824. * Return: 0 if all went well, else returns appropriate error value.
  825. */
  826. static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
  827. u32 dev_id, u8 clk_id,
  828. u32 flags, u8 state)
  829. {
  830. struct ti_sci_msg_req_set_clock_state req;
  831. struct ti_sci_msg_hdr *resp;
  832. struct ti_sci_info *info;
  833. struct ti_sci_xfer *xfer;
  834. int ret = 0;
  835. if (IS_ERR(handle))
  836. return PTR_ERR(handle);
  837. if (!handle)
  838. return -EINVAL;
  839. info = handle_to_ti_sci_info(handle);
  840. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_STATE,
  841. flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  842. (u32 *)&req, sizeof(req), sizeof(*resp));
  843. if (IS_ERR(xfer)) {
  844. ret = PTR_ERR(xfer);
  845. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  846. return ret;
  847. }
  848. req.dev_id = dev_id;
  849. req.clk_id = clk_id;
  850. req.request_state = state;
  851. ret = ti_sci_do_xfer(info, xfer);
  852. if (ret) {
  853. dev_err(info->dev, "Mbox send fail %d\n", ret);
  854. return ret;
  855. }
  856. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  857. if (!ti_sci_is_response_ack(resp))
  858. return -ENODEV;
  859. return ret;
  860. }
  861. /**
  862. * ti_sci_cmd_get_clock_state() - Get clock state helper
  863. * @handle: pointer to TI SCI handle
  864. * @dev_id: Device identifier this request is for
  865. * @clk_id: Clock identifier for the device for this request.
  866. * Each device has it's own set of clock inputs. This indexes
  867. * which clock input to modify.
  868. * @programmed_state: State requested for clock to move to
  869. * @current_state: State that the clock is currently in
  870. *
  871. * Return: 0 if all went well, else returns appropriate error value.
  872. */
  873. static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle,
  874. u32 dev_id, u8 clk_id,
  875. u8 *programmed_state, u8 *current_state)
  876. {
  877. struct ti_sci_msg_resp_get_clock_state *resp;
  878. struct ti_sci_msg_req_get_clock_state req;
  879. struct ti_sci_info *info;
  880. struct ti_sci_xfer *xfer;
  881. int ret = 0;
  882. if (IS_ERR(handle))
  883. return PTR_ERR(handle);
  884. if (!handle)
  885. return -EINVAL;
  886. if (!programmed_state && !current_state)
  887. return -EINVAL;
  888. info = handle_to_ti_sci_info(handle);
  889. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_STATE,
  890. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  891. (u32 *)&req, sizeof(req), sizeof(*resp));
  892. if (IS_ERR(xfer)) {
  893. ret = PTR_ERR(xfer);
  894. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  895. return ret;
  896. }
  897. req.dev_id = dev_id;
  898. req.clk_id = clk_id;
  899. ret = ti_sci_do_xfer(info, xfer);
  900. if (ret) {
  901. dev_err(info->dev, "Mbox send fail %d\n", ret);
  902. return ret;
  903. }
  904. resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->tx_message.buf;
  905. if (!ti_sci_is_response_ack(resp))
  906. return -ENODEV;
  907. if (programmed_state)
  908. *programmed_state = resp->programmed_state;
  909. if (current_state)
  910. *current_state = resp->current_state;
  911. return ret;
  912. }
  913. /**
  914. * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI
  915. * @handle: pointer to TI SCI handle
  916. * @dev_id: Device identifier this request is for
  917. * @clk_id: Clock identifier for the device for this request.
  918. * Each device has it's own set of clock inputs. This indexes
  919. * which clock input to modify.
  920. * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false'
  921. * @can_change_freq: 'true' if frequency change is desired, else 'false'
  922. * @enable_input_term: 'true' if input termination is desired, else 'false'
  923. *
  924. * Return: 0 if all went well, else returns appropriate error value.
  925. */
  926. static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id,
  927. u8 clk_id, bool needs_ssc, bool can_change_freq,
  928. bool enable_input_term)
  929. {
  930. u32 flags = 0;
  931. flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0;
  932. flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0;
  933. flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0;
  934. return ti_sci_set_clock_state(handle, dev_id, clk_id, flags,
  935. MSG_CLOCK_SW_STATE_REQ);
  936. }
  937. /**
  938. * ti_sci_cmd_idle_clock() - Idle a clock which is in our control
  939. * @handle: pointer to TI SCI handle
  940. * @dev_id: Device identifier this request is for
  941. * @clk_id: Clock identifier for the device for this request.
  942. * Each device has it's own set of clock inputs. This indexes
  943. * which clock input to modify.
  944. *
  945. * NOTE: This clock must have been requested by get_clock previously.
  946. *
  947. * Return: 0 if all went well, else returns appropriate error value.
  948. */
  949. static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle,
  950. u32 dev_id, u8 clk_id)
  951. {
  952. return ti_sci_set_clock_state(handle, dev_id, clk_id, 0,
  953. MSG_CLOCK_SW_STATE_UNREQ);
  954. }
  955. /**
  956. * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI
  957. * @handle: pointer to TI SCI handle
  958. * @dev_id: Device identifier this request is for
  959. * @clk_id: Clock identifier for the device for this request.
  960. * Each device has it's own set of clock inputs. This indexes
  961. * which clock input to modify.
  962. *
  963. * NOTE: This clock must have been requested by get_clock previously.
  964. *
  965. * Return: 0 if all went well, else returns appropriate error value.
  966. */
  967. static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle,
  968. u32 dev_id, u8 clk_id)
  969. {
  970. return ti_sci_set_clock_state(handle, dev_id, clk_id, 0,
  971. MSG_CLOCK_SW_STATE_AUTO);
  972. }
  973. /**
  974. * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed
  975. * @handle: pointer to TI SCI handle
  976. * @dev_id: Device identifier this request is for
  977. * @clk_id: Clock identifier for the device for this request.
  978. * Each device has it's own set of clock inputs. This indexes
  979. * which clock input to modify.
  980. * @req_state: state indicating if the clock is auto managed
  981. *
  982. * Return: 0 if all went well, else returns appropriate error value.
  983. */
  984. static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle,
  985. u32 dev_id, u8 clk_id, bool *req_state)
  986. {
  987. u8 state = 0;
  988. int ret;
  989. if (!req_state)
  990. return -EINVAL;
  991. ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL);
  992. if (ret)
  993. return ret;
  994. *req_state = (state == MSG_CLOCK_SW_STATE_AUTO);
  995. return 0;
  996. }
  997. /**
  998. * ti_sci_cmd_clk_is_on() - Is the clock ON
  999. * @handle: pointer to TI SCI handle
  1000. * @dev_id: Device identifier this request is for
  1001. * @clk_id: Clock identifier for the device for this request.
  1002. * Each device has it's own set of clock inputs. This indexes
  1003. * which clock input to modify.
  1004. * @req_state: state indicating if the clock is managed by us and enabled
  1005. * @curr_state: state indicating if the clock is ready for operation
  1006. *
  1007. * Return: 0 if all went well, else returns appropriate error value.
  1008. */
  1009. static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id,
  1010. u8 clk_id, bool *req_state, bool *curr_state)
  1011. {
  1012. u8 c_state = 0, r_state = 0;
  1013. int ret;
  1014. if (!req_state && !curr_state)
  1015. return -EINVAL;
  1016. ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
  1017. &r_state, &c_state);
  1018. if (ret)
  1019. return ret;
  1020. if (req_state)
  1021. *req_state = (r_state == MSG_CLOCK_SW_STATE_REQ);
  1022. if (curr_state)
  1023. *curr_state = (c_state == MSG_CLOCK_HW_STATE_READY);
  1024. return 0;
  1025. }
  1026. /**
  1027. * ti_sci_cmd_clk_is_off() - Is the clock OFF
  1028. * @handle: pointer to TI SCI handle
  1029. * @dev_id: Device identifier this request is for
  1030. * @clk_id: Clock identifier for the device for this request.
  1031. * Each device has it's own set of clock inputs. This indexes
  1032. * which clock input to modify.
  1033. * @req_state: state indicating if the clock is managed by us and disabled
  1034. * @curr_state: state indicating if the clock is NOT ready for operation
  1035. *
  1036. * Return: 0 if all went well, else returns appropriate error value.
  1037. */
  1038. static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id,
  1039. u8 clk_id, bool *req_state, bool *curr_state)
  1040. {
  1041. u8 c_state = 0, r_state = 0;
  1042. int ret;
  1043. if (!req_state && !curr_state)
  1044. return -EINVAL;
  1045. ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
  1046. &r_state, &c_state);
  1047. if (ret)
  1048. return ret;
  1049. if (req_state)
  1050. *req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ);
  1051. if (curr_state)
  1052. *curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY);
  1053. return 0;
  1054. }
  1055. /**
  1056. * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock
  1057. * @handle: pointer to TI SCI handle
  1058. * @dev_id: Device identifier this request is for
  1059. * @clk_id: Clock identifier for the device for this request.
  1060. * Each device has it's own set of clock inputs. This indexes
  1061. * which clock input to modify.
  1062. * @parent_id: Parent clock identifier to set
  1063. *
  1064. * Return: 0 if all went well, else returns appropriate error value.
  1065. */
  1066. static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
  1067. u32 dev_id, u8 clk_id, u8 parent_id)
  1068. {
  1069. struct ti_sci_msg_req_set_clock_parent req;
  1070. struct ti_sci_msg_hdr *resp;
  1071. struct ti_sci_info *info;
  1072. struct ti_sci_xfer *xfer;
  1073. int ret = 0;
  1074. if (IS_ERR(handle))
  1075. return PTR_ERR(handle);
  1076. if (!handle)
  1077. return -EINVAL;
  1078. info = handle_to_ti_sci_info(handle);
  1079. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_PARENT,
  1080. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1081. (u32 *)&req, sizeof(req), sizeof(*resp));
  1082. if (IS_ERR(xfer)) {
  1083. ret = PTR_ERR(xfer);
  1084. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1085. return ret;
  1086. }
  1087. req.dev_id = dev_id;
  1088. req.clk_id = clk_id;
  1089. req.parent_id = parent_id;
  1090. ret = ti_sci_do_xfer(info, xfer);
  1091. if (ret) {
  1092. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1093. return ret;
  1094. }
  1095. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  1096. if (!ti_sci_is_response_ack(resp))
  1097. return -ENODEV;
  1098. return ret;
  1099. }
  1100. /**
  1101. * ti_sci_cmd_clk_get_parent() - Get current parent clock source
  1102. * @handle: pointer to TI SCI handle
  1103. * @dev_id: Device identifier this request is for
  1104. * @clk_id: Clock identifier for the device for this request.
  1105. * Each device has it's own set of clock inputs. This indexes
  1106. * which clock input to modify.
  1107. * @parent_id: Current clock parent
  1108. *
  1109. * Return: 0 if all went well, else returns appropriate error value.
  1110. */
  1111. static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle,
  1112. u32 dev_id, u8 clk_id, u8 *parent_id)
  1113. {
  1114. struct ti_sci_msg_resp_get_clock_parent *resp;
  1115. struct ti_sci_msg_req_get_clock_parent req;
  1116. struct ti_sci_info *info;
  1117. struct ti_sci_xfer *xfer;
  1118. int ret = 0;
  1119. if (IS_ERR(handle))
  1120. return PTR_ERR(handle);
  1121. if (!handle || !parent_id)
  1122. return -EINVAL;
  1123. info = handle_to_ti_sci_info(handle);
  1124. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_PARENT,
  1125. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1126. (u32 *)&req, sizeof(req), sizeof(*resp));
  1127. if (IS_ERR(xfer)) {
  1128. ret = PTR_ERR(xfer);
  1129. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1130. return ret;
  1131. }
  1132. req.dev_id = dev_id;
  1133. req.clk_id = clk_id;
  1134. ret = ti_sci_do_xfer(info, xfer);
  1135. if (ret) {
  1136. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1137. return ret;
  1138. }
  1139. resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->tx_message.buf;
  1140. if (!ti_sci_is_response_ack(resp))
  1141. ret = -ENODEV;
  1142. else
  1143. *parent_id = resp->parent_id;
  1144. return ret;
  1145. }
  1146. /**
  1147. * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source
  1148. * @handle: pointer to TI SCI handle
  1149. * @dev_id: Device identifier this request is for
  1150. * @clk_id: Clock identifier for the device for this request.
  1151. * Each device has it's own set of clock inputs. This indexes
  1152. * which clock input to modify.
  1153. * @num_parents: Returns he number of parents to the current clock.
  1154. *
  1155. * Return: 0 if all went well, else returns appropriate error value.
  1156. */
  1157. static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle,
  1158. u32 dev_id, u8 clk_id,
  1159. u8 *num_parents)
  1160. {
  1161. struct ti_sci_msg_resp_get_clock_num_parents *resp;
  1162. struct ti_sci_msg_req_get_clock_num_parents req;
  1163. struct ti_sci_info *info;
  1164. struct ti_sci_xfer *xfer;
  1165. int ret = 0;
  1166. if (IS_ERR(handle))
  1167. return PTR_ERR(handle);
  1168. if (!handle || !num_parents)
  1169. return -EINVAL;
  1170. info = handle_to_ti_sci_info(handle);
  1171. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS,
  1172. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1173. (u32 *)&req, sizeof(req), sizeof(*resp));
  1174. if (IS_ERR(xfer)) {
  1175. ret = PTR_ERR(xfer);
  1176. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1177. return ret;
  1178. }
  1179. req.dev_id = dev_id;
  1180. req.clk_id = clk_id;
  1181. ret = ti_sci_do_xfer(info, xfer);
  1182. if (ret) {
  1183. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1184. return ret;
  1185. }
  1186. resp = (struct ti_sci_msg_resp_get_clock_num_parents *)
  1187. xfer->tx_message.buf;
  1188. if (!ti_sci_is_response_ack(resp))
  1189. ret = -ENODEV;
  1190. else
  1191. *num_parents = resp->num_parents;
  1192. return ret;
  1193. }
  1194. /**
  1195. * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency
  1196. * @handle: pointer to TI SCI handle
  1197. * @dev_id: Device identifier this request is for
  1198. * @clk_id: Clock identifier for the device for this request.
  1199. * Each device has it's own set of clock inputs. This indexes
  1200. * which clock input to modify.
  1201. * @min_freq: The minimum allowable frequency in Hz. This is the minimum
  1202. * allowable programmed frequency and does not account for clock
  1203. * tolerances and jitter.
  1204. * @target_freq: The target clock frequency in Hz. A frequency will be
  1205. * processed as close to this target frequency as possible.
  1206. * @max_freq: The maximum allowable frequency in Hz. This is the maximum
  1207. * allowable programmed frequency and does not account for clock
  1208. * tolerances and jitter.
  1209. * @match_freq: Frequency match in Hz response.
  1210. *
  1211. * Return: 0 if all went well, else returns appropriate error value.
  1212. */
  1213. static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
  1214. u32 dev_id, u8 clk_id, u64 min_freq,
  1215. u64 target_freq, u64 max_freq,
  1216. u64 *match_freq)
  1217. {
  1218. struct ti_sci_msg_resp_query_clock_freq *resp;
  1219. struct ti_sci_msg_req_query_clock_freq req;
  1220. struct ti_sci_info *info;
  1221. struct ti_sci_xfer *xfer;
  1222. int ret = 0;
  1223. if (IS_ERR(handle))
  1224. return PTR_ERR(handle);
  1225. if (!handle || !match_freq)
  1226. return -EINVAL;
  1227. info = handle_to_ti_sci_info(handle);
  1228. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_QUERY_CLOCK_FREQ,
  1229. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1230. (u32 *)&req, sizeof(req), sizeof(*resp));
  1231. if (IS_ERR(xfer)) {
  1232. ret = PTR_ERR(xfer);
  1233. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1234. return ret;
  1235. }
  1236. req.dev_id = dev_id;
  1237. req.clk_id = clk_id;
  1238. req.min_freq_hz = min_freq;
  1239. req.target_freq_hz = target_freq;
  1240. req.max_freq_hz = max_freq;
  1241. ret = ti_sci_do_xfer(info, xfer);
  1242. if (ret) {
  1243. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1244. return ret;
  1245. }
  1246. resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->tx_message.buf;
  1247. if (!ti_sci_is_response_ack(resp))
  1248. ret = -ENODEV;
  1249. else
  1250. *match_freq = resp->freq_hz;
  1251. return ret;
  1252. }
  1253. /**
  1254. * ti_sci_cmd_clk_set_freq() - Set a frequency for clock
  1255. * @handle: pointer to TI SCI handle
  1256. * @dev_id: Device identifier this request is for
  1257. * @clk_id: Clock identifier for the device for this request.
  1258. * Each device has it's own set of clock inputs. This indexes
  1259. * which clock input to modify.
  1260. * @min_freq: The minimum allowable frequency in Hz. This is the minimum
  1261. * allowable programmed frequency and does not account for clock
  1262. * tolerances and jitter.
  1263. * @target_freq: The target clock frequency in Hz. A frequency will be
  1264. * processed as close to this target frequency as possible.
  1265. * @max_freq: The maximum allowable frequency in Hz. This is the maximum
  1266. * allowable programmed frequency and does not account for clock
  1267. * tolerances and jitter.
  1268. *
  1269. * Return: 0 if all went well, else returns appropriate error value.
  1270. */
  1271. static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
  1272. u32 dev_id, u8 clk_id, u64 min_freq,
  1273. u64 target_freq, u64 max_freq)
  1274. {
  1275. struct ti_sci_msg_req_set_clock_freq req;
  1276. struct ti_sci_msg_hdr *resp;
  1277. struct ti_sci_info *info;
  1278. struct ti_sci_xfer *xfer;
  1279. int ret = 0;
  1280. if (IS_ERR(handle))
  1281. return PTR_ERR(handle);
  1282. if (!handle)
  1283. return -EINVAL;
  1284. info = handle_to_ti_sci_info(handle);
  1285. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_FREQ,
  1286. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1287. (u32 *)&req, sizeof(req), sizeof(*resp));
  1288. if (IS_ERR(xfer)) {
  1289. ret = PTR_ERR(xfer);
  1290. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1291. return ret;
  1292. }
  1293. req.dev_id = dev_id;
  1294. req.clk_id = clk_id;
  1295. req.min_freq_hz = min_freq;
  1296. req.target_freq_hz = target_freq;
  1297. req.max_freq_hz = max_freq;
  1298. ret = ti_sci_do_xfer(info, xfer);
  1299. if (ret) {
  1300. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1301. return ret;
  1302. }
  1303. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  1304. if (!ti_sci_is_response_ack(resp))
  1305. return -ENODEV;
  1306. return ret;
  1307. }
  1308. /**
  1309. * ti_sci_cmd_clk_get_freq() - Get current frequency
  1310. * @handle: pointer to TI SCI handle
  1311. * @dev_id: Device identifier this request is for
  1312. * @clk_id: Clock identifier for the device for this request.
  1313. * Each device has it's own set of clock inputs. This indexes
  1314. * which clock input to modify.
  1315. * @freq: Currently frequency in Hz
  1316. *
  1317. * Return: 0 if all went well, else returns appropriate error value.
  1318. */
  1319. static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
  1320. u32 dev_id, u8 clk_id, u64 *freq)
  1321. {
  1322. struct ti_sci_msg_resp_get_clock_freq *resp;
  1323. struct ti_sci_msg_req_get_clock_freq req;
  1324. struct ti_sci_info *info;
  1325. struct ti_sci_xfer *xfer;
  1326. int ret = 0;
  1327. if (IS_ERR(handle))
  1328. return PTR_ERR(handle);
  1329. if (!handle || !freq)
  1330. return -EINVAL;
  1331. info = handle_to_ti_sci_info(handle);
  1332. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_FREQ,
  1333. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1334. (u32 *)&req, sizeof(req), sizeof(*resp));
  1335. if (IS_ERR(xfer)) {
  1336. ret = PTR_ERR(xfer);
  1337. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1338. return ret;
  1339. }
  1340. req.dev_id = dev_id;
  1341. req.clk_id = clk_id;
  1342. ret = ti_sci_do_xfer(info, xfer);
  1343. if (ret) {
  1344. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1345. return ret;
  1346. }
  1347. resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->tx_message.buf;
  1348. if (!ti_sci_is_response_ack(resp))
  1349. ret = -ENODEV;
  1350. else
  1351. *freq = resp->freq_hz;
  1352. return ret;
  1353. }
  1354. /**
  1355. * ti_sci_cmd_core_reboot() - Command to request system reset
  1356. * @handle: pointer to TI SCI handle
  1357. *
  1358. * Return: 0 if all went well, else returns appropriate error value.
  1359. */
  1360. static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
  1361. {
  1362. struct ti_sci_msg_req_reboot req;
  1363. struct ti_sci_msg_hdr *resp;
  1364. struct ti_sci_info *info;
  1365. struct ti_sci_xfer *xfer;
  1366. int ret = 0;
  1367. if (IS_ERR(handle))
  1368. return PTR_ERR(handle);
  1369. if (!handle)
  1370. return -EINVAL;
  1371. info = handle_to_ti_sci_info(handle);
  1372. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SYS_RESET,
  1373. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1374. (u32 *)&req, sizeof(req), sizeof(*resp));
  1375. if (IS_ERR(xfer)) {
  1376. ret = PTR_ERR(xfer);
  1377. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1378. return ret;
  1379. }
  1380. req.domain = 0;
  1381. ret = ti_sci_do_xfer(info, xfer);
  1382. if (ret) {
  1383. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1384. return ret;
  1385. }
  1386. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  1387. if (!ti_sci_is_response_ack(resp))
  1388. return -ENODEV;
  1389. return ret;
  1390. }
  1391. /**
  1392. * ti_sci_get_resource_range - Helper to get a range of resources assigned
  1393. * to a host. Resource is uniquely identified by
  1394. * type and subtype.
  1395. * @handle: Pointer to TISCI handle.
  1396. * @dev_id: TISCI device ID.
  1397. * @subtype: Resource assignment subtype that is being requested
  1398. * from the given device.
  1399. * @s_host: Host processor ID to which the resources are allocated
  1400. * @range_start: Start index of the resource range
  1401. * @range_num: Number of resources in the range
  1402. *
  1403. * Return: 0 if all went fine, else return appropriate error.
  1404. */
  1405. static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
  1406. u32 dev_id, u8 subtype, u8 s_host,
  1407. u16 *range_start, u16 *range_num)
  1408. {
  1409. struct ti_sci_msg_resp_get_resource_range *resp;
  1410. struct ti_sci_msg_req_get_resource_range req;
  1411. struct ti_sci_xfer *xfer;
  1412. struct ti_sci_info *info;
  1413. int ret = 0;
  1414. if (IS_ERR(handle))
  1415. return PTR_ERR(handle);
  1416. if (!handle)
  1417. return -EINVAL;
  1418. info = handle_to_ti_sci_info(handle);
  1419. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE,
  1420. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1421. (u32 *)&req, sizeof(req), sizeof(*resp));
  1422. if (IS_ERR(xfer)) {
  1423. ret = PTR_ERR(xfer);
  1424. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1425. return ret;
  1426. }
  1427. req.secondary_host = s_host;
  1428. req.type = dev_id & MSG_RM_RESOURCE_TYPE_MASK;
  1429. req.subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
  1430. ret = ti_sci_do_xfer(info, xfer);
  1431. if (ret) {
  1432. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1433. goto fail;
  1434. }
  1435. resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->tx_message.buf;
  1436. if (!ti_sci_is_response_ack(resp)) {
  1437. ret = -ENODEV;
  1438. } else if (!resp->range_start && !resp->range_num) {
  1439. ret = -ENODEV;
  1440. } else {
  1441. *range_start = resp->range_start;
  1442. *range_num = resp->range_num;
  1443. };
  1444. fail:
  1445. return ret;
  1446. }
  1447. static int __maybe_unused
  1448. ti_sci_cmd_get_resource_range_static(const struct ti_sci_handle *handle,
  1449. u32 dev_id, u8 subtype,
  1450. u16 *range_start, u16 *range_num)
  1451. {
  1452. struct ti_sci_resource_static_data *data;
  1453. int i = 0;
  1454. while (1) {
  1455. data = &rm_static_data[i];
  1456. if (!data->dev_id)
  1457. return -EINVAL;
  1458. if (data->dev_id != dev_id || data->subtype != subtype) {
  1459. i++;
  1460. continue;
  1461. }
  1462. *range_start = data->range_start;
  1463. *range_num = data->range_num;
  1464. return 0;
  1465. }
  1466. return -EINVAL;
  1467. }
  1468. /**
  1469. * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host
  1470. * that is same as ti sci interface host.
  1471. * @handle: Pointer to TISCI handle.
  1472. * @dev_id: TISCI device ID.
  1473. * @subtype: Resource assignment subtype that is being requested
  1474. * from the given device.
  1475. * @range_start: Start index of the resource range
  1476. * @range_num: Number of resources in the range
  1477. *
  1478. * Return: 0 if all went fine, else return appropriate error.
  1479. */
  1480. static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
  1481. u32 dev_id, u8 subtype,
  1482. u16 *range_start, u16 *range_num)
  1483. {
  1484. return ti_sci_get_resource_range(handle, dev_id, subtype,
  1485. TI_SCI_IRQ_SECONDARY_HOST_INVALID,
  1486. range_start, range_num);
  1487. }
  1488. /**
  1489. * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources
  1490. * assigned to a specified host.
  1491. * @handle: Pointer to TISCI handle.
  1492. * @dev_id: TISCI device ID.
  1493. * @subtype: Resource assignment subtype that is being requested
  1494. * from the given device.
  1495. * @s_host: Host processor ID to which the resources are allocated
  1496. * @range_start: Start index of the resource range
  1497. * @range_num: Number of resources in the range
  1498. *
  1499. * Return: 0 if all went fine, else return appropriate error.
  1500. */
  1501. static
  1502. int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
  1503. u32 dev_id, u8 subtype, u8 s_host,
  1504. u16 *range_start, u16 *range_num)
  1505. {
  1506. return ti_sci_get_resource_range(handle, dev_id, subtype, s_host,
  1507. range_start, range_num);
  1508. }
  1509. /**
  1510. * ti_sci_cmd_query_msmc() - Command to query currently available msmc memory
  1511. * @handle: pointer to TI SCI handle
  1512. * @msms_start: MSMC start as returned by tisci
  1513. * @msmc_end: MSMC end as returned by tisci
  1514. *
  1515. * Return: 0 if all went well, else returns appropriate error value.
  1516. */
  1517. static int ti_sci_cmd_query_msmc(const struct ti_sci_handle *handle,
  1518. u64 *msmc_start, u64 *msmc_end)
  1519. {
  1520. struct ti_sci_msg_resp_query_msmc *resp;
  1521. struct ti_sci_msg_hdr req;
  1522. struct ti_sci_info *info;
  1523. struct ti_sci_xfer *xfer;
  1524. int ret = 0;
  1525. if (IS_ERR(handle))
  1526. return PTR_ERR(handle);
  1527. if (!handle)
  1528. return -EINVAL;
  1529. info = handle_to_ti_sci_info(handle);
  1530. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_QUERY_MSMC,
  1531. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1532. (u32 *)&req, sizeof(req), sizeof(*resp));
  1533. if (IS_ERR(xfer)) {
  1534. ret = PTR_ERR(xfer);
  1535. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1536. return ret;
  1537. }
  1538. ret = ti_sci_do_xfer(info, xfer);
  1539. if (ret) {
  1540. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1541. return ret;
  1542. }
  1543. resp = (struct ti_sci_msg_resp_query_msmc *)xfer->tx_message.buf;
  1544. if (!ti_sci_is_response_ack(resp))
  1545. return -ENODEV;
  1546. *msmc_start = ((u64)resp->msmc_start_high << TISCI_ADDR_HIGH_SHIFT) |
  1547. resp->msmc_start_low;
  1548. *msmc_end = ((u64)resp->msmc_end_high << TISCI_ADDR_HIGH_SHIFT) |
  1549. resp->msmc_end_low;
  1550. return ret;
  1551. }
  1552. /**
  1553. * ti_sci_cmd_proc_request() - Command to request a physical processor control
  1554. * @handle: Pointer to TI SCI handle
  1555. * @proc_id: Processor ID this request is for
  1556. *
  1557. * Return: 0 if all went well, else returns appropriate error value.
  1558. */
  1559. static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle,
  1560. u8 proc_id)
  1561. {
  1562. struct ti_sci_msg_req_proc_request req;
  1563. struct ti_sci_msg_hdr *resp;
  1564. struct ti_sci_info *info;
  1565. struct ti_sci_xfer *xfer;
  1566. int ret = 0;
  1567. if (IS_ERR(handle))
  1568. return PTR_ERR(handle);
  1569. if (!handle)
  1570. return -EINVAL;
  1571. info = handle_to_ti_sci_info(handle);
  1572. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_REQUEST,
  1573. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1574. (u32 *)&req, sizeof(req), sizeof(*resp));
  1575. if (IS_ERR(xfer)) {
  1576. ret = PTR_ERR(xfer);
  1577. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1578. return ret;
  1579. }
  1580. req.processor_id = proc_id;
  1581. ret = ti_sci_do_xfer(info, xfer);
  1582. if (ret) {
  1583. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1584. return ret;
  1585. }
  1586. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  1587. if (!ti_sci_is_response_ack(resp))
  1588. ret = -ENODEV;
  1589. return ret;
  1590. }
  1591. /**
  1592. * ti_sci_cmd_proc_release() - Command to release a physical processor control
  1593. * @handle: Pointer to TI SCI handle
  1594. * @proc_id: Processor ID this request is for
  1595. *
  1596. * Return: 0 if all went well, else returns appropriate error value.
  1597. */
  1598. static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle,
  1599. u8 proc_id)
  1600. {
  1601. struct ti_sci_msg_req_proc_release req;
  1602. struct ti_sci_msg_hdr *resp;
  1603. struct ti_sci_info *info;
  1604. struct ti_sci_xfer *xfer;
  1605. int ret = 0;
  1606. if (IS_ERR(handle))
  1607. return PTR_ERR(handle);
  1608. if (!handle)
  1609. return -EINVAL;
  1610. info = handle_to_ti_sci_info(handle);
  1611. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_RELEASE,
  1612. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1613. (u32 *)&req, sizeof(req), sizeof(*resp));
  1614. if (IS_ERR(xfer)) {
  1615. ret = PTR_ERR(xfer);
  1616. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1617. return ret;
  1618. }
  1619. req.processor_id = proc_id;
  1620. ret = ti_sci_do_xfer(info, xfer);
  1621. if (ret) {
  1622. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1623. return ret;
  1624. }
  1625. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  1626. if (!ti_sci_is_response_ack(resp))
  1627. ret = -ENODEV;
  1628. return ret;
  1629. }
  1630. /**
  1631. * ti_sci_cmd_proc_handover() - Command to handover a physical processor
  1632. * control to a host in the processor's access
  1633. * control list.
  1634. * @handle: Pointer to TI SCI handle
  1635. * @proc_id: Processor ID this request is for
  1636. * @host_id: Host ID to get the control of the processor
  1637. *
  1638. * Return: 0 if all went well, else returns appropriate error value.
  1639. */
  1640. static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle,
  1641. u8 proc_id, u8 host_id)
  1642. {
  1643. struct ti_sci_msg_req_proc_handover req;
  1644. struct ti_sci_msg_hdr *resp;
  1645. struct ti_sci_info *info;
  1646. struct ti_sci_xfer *xfer;
  1647. int ret = 0;
  1648. if (IS_ERR(handle))
  1649. return PTR_ERR(handle);
  1650. if (!handle)
  1651. return -EINVAL;
  1652. info = handle_to_ti_sci_info(handle);
  1653. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_HANDOVER,
  1654. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1655. (u32 *)&req, sizeof(req), sizeof(*resp));
  1656. if (IS_ERR(xfer)) {
  1657. ret = PTR_ERR(xfer);
  1658. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1659. return ret;
  1660. }
  1661. req.processor_id = proc_id;
  1662. req.host_id = host_id;
  1663. ret = ti_sci_do_xfer(info, xfer);
  1664. if (ret) {
  1665. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1666. return ret;
  1667. }
  1668. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  1669. if (!ti_sci_is_response_ack(resp))
  1670. ret = -ENODEV;
  1671. return ret;
  1672. }
  1673. /**
  1674. * ti_sci_cmd_set_proc_boot_cfg() - Command to set the processor boot
  1675. * configuration flags
  1676. * @handle: Pointer to TI SCI handle
  1677. * @proc_id: Processor ID this request is for
  1678. * @config_flags_set: Configuration flags to be set
  1679. * @config_flags_clear: Configuration flags to be cleared.
  1680. *
  1681. * Return: 0 if all went well, else returns appropriate error value.
  1682. */
  1683. static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle,
  1684. u8 proc_id, u64 bootvector,
  1685. u32 config_flags_set,
  1686. u32 config_flags_clear)
  1687. {
  1688. struct ti_sci_msg_req_set_proc_boot_config req;
  1689. struct ti_sci_msg_hdr *resp;
  1690. struct ti_sci_info *info;
  1691. struct ti_sci_xfer *xfer;
  1692. int ret = 0;
  1693. if (IS_ERR(handle))
  1694. return PTR_ERR(handle);
  1695. if (!handle)
  1696. return -EINVAL;
  1697. info = handle_to_ti_sci_info(handle);
  1698. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_SET_PROC_BOOT_CONFIG,
  1699. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1700. (u32 *)&req, sizeof(req), sizeof(*resp));
  1701. if (IS_ERR(xfer)) {
  1702. ret = PTR_ERR(xfer);
  1703. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1704. return ret;
  1705. }
  1706. req.processor_id = proc_id;
  1707. req.bootvector_low = bootvector & TISCI_ADDR_LOW_MASK;
  1708. req.bootvector_high = (bootvector & TISCI_ADDR_HIGH_MASK) >>
  1709. TISCI_ADDR_HIGH_SHIFT;
  1710. req.config_flags_set = config_flags_set;
  1711. req.config_flags_clear = config_flags_clear;
  1712. ret = ti_sci_do_xfer(info, xfer);
  1713. if (ret) {
  1714. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1715. return ret;
  1716. }
  1717. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  1718. if (!ti_sci_is_response_ack(resp))
  1719. ret = -ENODEV;
  1720. return ret;
  1721. }
  1722. /**
  1723. * ti_sci_cmd_set_proc_boot_ctrl() - Command to set the processor boot
  1724. * control flags
  1725. * @handle: Pointer to TI SCI handle
  1726. * @proc_id: Processor ID this request is for
  1727. * @control_flags_set: Control flags to be set
  1728. * @control_flags_clear: Control flags to be cleared
  1729. *
  1730. * Return: 0 if all went well, else returns appropriate error value.
  1731. */
  1732. static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle,
  1733. u8 proc_id, u32 control_flags_set,
  1734. u32 control_flags_clear)
  1735. {
  1736. struct ti_sci_msg_req_set_proc_boot_ctrl req;
  1737. struct ti_sci_msg_hdr *resp;
  1738. struct ti_sci_info *info;
  1739. struct ti_sci_xfer *xfer;
  1740. int ret = 0;
  1741. if (IS_ERR(handle))
  1742. return PTR_ERR(handle);
  1743. if (!handle)
  1744. return -EINVAL;
  1745. info = handle_to_ti_sci_info(handle);
  1746. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_SET_PROC_BOOT_CTRL,
  1747. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1748. (u32 *)&req, sizeof(req), sizeof(*resp));
  1749. if (IS_ERR(xfer)) {
  1750. ret = PTR_ERR(xfer);
  1751. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1752. return ret;
  1753. }
  1754. req.processor_id = proc_id;
  1755. req.control_flags_set = control_flags_set;
  1756. req.control_flags_clear = control_flags_clear;
  1757. ret = ti_sci_do_xfer(info, xfer);
  1758. if (ret) {
  1759. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1760. return ret;
  1761. }
  1762. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  1763. if (!ti_sci_is_response_ack(resp))
  1764. ret = -ENODEV;
  1765. return ret;
  1766. }
  1767. /**
  1768. * ti_sci_cmd_proc_auth_boot_image() - Command to authenticate and load the
  1769. * image and then set the processor configuration flags.
  1770. * @handle: Pointer to TI SCI handle
  1771. * @image_addr: Memory address at which payload image and certificate is
  1772. * located in memory, this is updated if the image data is
  1773. * moved during authentication.
  1774. * @image_size: This is updated with the final size of the image after
  1775. * authentication.
  1776. *
  1777. * Return: 0 if all went well, else returns appropriate error value.
  1778. */
  1779. static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle,
  1780. u64 *image_addr, u32 *image_size)
  1781. {
  1782. struct ti_sci_msg_req_proc_auth_boot_image req;
  1783. struct ti_sci_msg_resp_proc_auth_boot_image *resp;
  1784. struct ti_sci_info *info;
  1785. struct ti_sci_xfer *xfer;
  1786. int ret = 0;
  1787. if (IS_ERR(handle))
  1788. return PTR_ERR(handle);
  1789. if (!handle)
  1790. return -EINVAL;
  1791. info = handle_to_ti_sci_info(handle);
  1792. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_AUTH_BOOT_IMIAGE,
  1793. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1794. (u32 *)&req, sizeof(req), sizeof(*resp));
  1795. if (IS_ERR(xfer)) {
  1796. ret = PTR_ERR(xfer);
  1797. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1798. return ret;
  1799. }
  1800. req.cert_addr_low = *image_addr & TISCI_ADDR_LOW_MASK;
  1801. req.cert_addr_high = (*image_addr & TISCI_ADDR_HIGH_MASK) >>
  1802. TISCI_ADDR_HIGH_SHIFT;
  1803. ret = ti_sci_do_xfer(info, xfer);
  1804. if (ret) {
  1805. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1806. return ret;
  1807. }
  1808. resp = (struct ti_sci_msg_resp_proc_auth_boot_image *)xfer->tx_message.buf;
  1809. if (!ti_sci_is_response_ack(resp))
  1810. return -ENODEV;
  1811. *image_addr = (resp->image_addr_low & TISCI_ADDR_LOW_MASK) |
  1812. (((u64)resp->image_addr_high <<
  1813. TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK);
  1814. *image_size = resp->image_size;
  1815. return ret;
  1816. }
  1817. /**
  1818. * ti_sci_cmd_get_proc_boot_status() - Command to get the processor boot status
  1819. * @handle: Pointer to TI SCI handle
  1820. * @proc_id: Processor ID this request is for
  1821. *
  1822. * Return: 0 if all went well, else returns appropriate error value.
  1823. */
  1824. static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle,
  1825. u8 proc_id, u64 *bv, u32 *cfg_flags,
  1826. u32 *ctrl_flags, u32 *sts_flags)
  1827. {
  1828. struct ti_sci_msg_resp_get_proc_boot_status *resp;
  1829. struct ti_sci_msg_req_get_proc_boot_status req;
  1830. struct ti_sci_info *info;
  1831. struct ti_sci_xfer *xfer;
  1832. int ret = 0;
  1833. if (IS_ERR(handle))
  1834. return PTR_ERR(handle);
  1835. if (!handle)
  1836. return -EINVAL;
  1837. info = handle_to_ti_sci_info(handle);
  1838. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_GET_PROC_BOOT_STATUS,
  1839. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1840. (u32 *)&req, sizeof(req), sizeof(*resp));
  1841. if (IS_ERR(xfer)) {
  1842. ret = PTR_ERR(xfer);
  1843. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1844. return ret;
  1845. }
  1846. req.processor_id = proc_id;
  1847. ret = ti_sci_do_xfer(info, xfer);
  1848. if (ret) {
  1849. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1850. return ret;
  1851. }
  1852. resp = (struct ti_sci_msg_resp_get_proc_boot_status *)
  1853. xfer->tx_message.buf;
  1854. if (!ti_sci_is_response_ack(resp))
  1855. return -ENODEV;
  1856. *bv = (resp->bootvector_low & TISCI_ADDR_LOW_MASK) |
  1857. (((u64)resp->bootvector_high <<
  1858. TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK);
  1859. *cfg_flags = resp->config_flags;
  1860. *ctrl_flags = resp->control_flags;
  1861. *sts_flags = resp->status_flags;
  1862. return ret;
  1863. }
  1864. /**
  1865. * ti_sci_proc_wait_boot_status_no_wait() - Helper function to wait for a
  1866. * processor boot status without requesting or
  1867. * waiting for a response.
  1868. * @proc_id: Processor ID this request is for
  1869. * @num_wait_iterations: Total number of iterations we will check before
  1870. * we will timeout and give up
  1871. * @num_match_iterations: How many iterations should we have continued
  1872. * status to account for status bits glitching.
  1873. * This is to make sure that match occurs for
  1874. * consecutive checks. This implies that the
  1875. * worst case should consider that the stable
  1876. * time should at the worst be num_wait_iterations
  1877. * num_match_iterations to prevent timeout.
  1878. * @delay_per_iteration_us: Specifies how long to wait (in micro seconds)
  1879. * between each status checks. This is the minimum
  1880. * duration, and overhead of register reads and
  1881. * checks are on top of this and can vary based on
  1882. * varied conditions.
  1883. * @delay_before_iterations_us: Specifies how long to wait (in micro seconds)
  1884. * before the very first check in the first
  1885. * iteration of status check loop. This is the
  1886. * minimum duration, and overhead of register
  1887. * reads and checks are.
  1888. * @status_flags_1_set_all_wait:If non-zero, Specifies that all bits of the
  1889. * status matching this field requested MUST be 1.
  1890. * @status_flags_1_set_any_wait:If non-zero, Specifies that at least one of the
  1891. * bits matching this field requested MUST be 1.
  1892. * @status_flags_1_clr_all_wait:If non-zero, Specifies that all bits of the
  1893. * status matching this field requested MUST be 0.
  1894. * @status_flags_1_clr_any_wait:If non-zero, Specifies that at least one of the
  1895. * bits matching this field requested MUST be 0.
  1896. *
  1897. * Return: 0 if all goes well, else appropriate error message
  1898. */
  1899. static int
  1900. ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle,
  1901. u8 proc_id,
  1902. u8 num_wait_iterations,
  1903. u8 num_match_iterations,
  1904. u8 delay_per_iteration_us,
  1905. u8 delay_before_iterations_us,
  1906. u32 status_flags_1_set_all_wait,
  1907. u32 status_flags_1_set_any_wait,
  1908. u32 status_flags_1_clr_all_wait,
  1909. u32 status_flags_1_clr_any_wait)
  1910. {
  1911. struct ti_sci_msg_req_wait_proc_boot_status req;
  1912. struct ti_sci_info *info;
  1913. struct ti_sci_xfer *xfer;
  1914. int ret = 0;
  1915. if (IS_ERR(handle))
  1916. return PTR_ERR(handle);
  1917. if (!handle)
  1918. return -EINVAL;
  1919. info = handle_to_ti_sci_info(handle);
  1920. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_WAIT_PROC_BOOT_STATUS,
  1921. TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
  1922. (u32 *)&req, sizeof(req), 0);
  1923. if (IS_ERR(xfer)) {
  1924. ret = PTR_ERR(xfer);
  1925. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  1926. return ret;
  1927. }
  1928. req.processor_id = proc_id;
  1929. req.num_wait_iterations = num_wait_iterations;
  1930. req.num_match_iterations = num_match_iterations;
  1931. req.delay_per_iteration_us = delay_per_iteration_us;
  1932. req.delay_before_iterations_us = delay_before_iterations_us;
  1933. req.status_flags_1_set_all_wait = status_flags_1_set_all_wait;
  1934. req.status_flags_1_set_any_wait = status_flags_1_set_any_wait;
  1935. req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait;
  1936. req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait;
  1937. ret = ti_sci_do_xfer(info, xfer);
  1938. if (ret)
  1939. dev_err(info->dev, "Mbox send fail %d\n", ret);
  1940. return ret;
  1941. }
  1942. /**
  1943. * ti_sci_cmd_proc_shutdown_no_wait() - Command to shutdown a core without
  1944. * requesting or waiting for a response. Note that this API call
  1945. * should be followed by placing the respective processor into
  1946. * either WFE or WFI mode.
  1947. * @handle: Pointer to TI SCI handle
  1948. * @proc_id: Processor ID this request is for
  1949. *
  1950. * Return: 0 if all went well, else returns appropriate error value.
  1951. */
  1952. static int ti_sci_cmd_proc_shutdown_no_wait(const struct ti_sci_handle *handle,
  1953. u8 proc_id)
  1954. {
  1955. int ret;
  1956. struct ti_sci_info *info;
  1957. if (IS_ERR(handle))
  1958. return PTR_ERR(handle);
  1959. if (!handle)
  1960. return -EINVAL;
  1961. info = handle_to_ti_sci_info(handle);
  1962. /*
  1963. * Send the core boot status wait message waiting for either WFE or
  1964. * WFI without requesting or waiting for a TISCI response with the
  1965. * maximum wait time to give us the best chance to get to the WFE/WFI
  1966. * command that should follow the invocation of this API before the
  1967. * DMSC-internal processing of this command times out. Note that
  1968. * waiting for the R5 WFE/WFI flags will also work on an ARMV8 type
  1969. * core as the related flag bit positions are the same.
  1970. */
  1971. ret = ti_sci_proc_wait_boot_status_no_wait(handle, proc_id,
  1972. U8_MAX, 100, U8_MAX, U8_MAX,
  1973. 0, PROC_BOOT_STATUS_FLAG_R5_WFE | PROC_BOOT_STATUS_FLAG_R5_WFI,
  1974. 0, 0);
  1975. if (ret) {
  1976. dev_err(info->dev, "Sending core %u wait message fail %d\n",
  1977. proc_id, ret);
  1978. return ret;
  1979. }
  1980. /*
  1981. * Release a processor managed by TISCI without requesting or waiting
  1982. * for a response.
  1983. */
  1984. ret = ti_sci_set_device_state_no_wait(handle, proc_id, 0,
  1985. MSG_DEVICE_SW_STATE_AUTO_OFF);
  1986. if (ret)
  1987. dev_err(info->dev, "Sending core %u shutdown message fail %d\n",
  1988. proc_id, ret);
  1989. return ret;
  1990. }
  1991. /**
  1992. * ti_sci_cmd_ring_config() - configure RA ring
  1993. * @handle: pointer to TI SCI handle
  1994. * @valid_params: Bitfield defining validity of ring configuration parameters.
  1995. * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
  1996. * @index: Ring index.
  1997. * @addr_lo: The ring base address lo 32 bits
  1998. * @addr_hi: The ring base address hi 32 bits
  1999. * @count: Number of ring elements.
  2000. * @mode: The mode of the ring
  2001. * @size: The ring element size.
  2002. * @order_id: Specifies the ring's bus order ID.
  2003. *
  2004. * Return: 0 if all went well, else returns appropriate error value.
  2005. *
  2006. * See @ti_sci_msg_rm_ring_cfg_req for more info.
  2007. */
  2008. static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle,
  2009. u32 valid_params, u16 nav_id, u16 index,
  2010. u32 addr_lo, u32 addr_hi, u32 count,
  2011. u8 mode, u8 size, u8 order_id)
  2012. {
  2013. struct ti_sci_msg_rm_ring_cfg_resp *resp;
  2014. struct ti_sci_msg_rm_ring_cfg_req req;
  2015. struct ti_sci_xfer *xfer;
  2016. struct ti_sci_info *info;
  2017. int ret = 0;
  2018. if (IS_ERR(handle))
  2019. return PTR_ERR(handle);
  2020. if (!handle)
  2021. return -EINVAL;
  2022. info = handle_to_ti_sci_info(handle);
  2023. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_RING_CFG,
  2024. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2025. (u32 *)&req, sizeof(req), sizeof(*resp));
  2026. if (IS_ERR(xfer)) {
  2027. ret = PTR_ERR(xfer);
  2028. dev_err(info->dev, "RM_RA:Message config failed(%d)\n", ret);
  2029. return ret;
  2030. }
  2031. req.valid_params = valid_params;
  2032. req.nav_id = nav_id;
  2033. req.index = index;
  2034. req.addr_lo = addr_lo;
  2035. req.addr_hi = addr_hi;
  2036. req.count = count;
  2037. req.mode = mode;
  2038. req.size = size;
  2039. req.order_id = order_id;
  2040. ret = ti_sci_do_xfer(info, xfer);
  2041. if (ret) {
  2042. dev_err(info->dev, "RM_RA:Mbox config send fail %d\n", ret);
  2043. goto fail;
  2044. }
  2045. resp = (struct ti_sci_msg_rm_ring_cfg_resp *)xfer->tx_message.buf;
  2046. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  2047. fail:
  2048. dev_dbg(info->dev, "RM_RA:config ring %u ret:%d\n", index, ret);
  2049. return ret;
  2050. }
  2051. static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
  2052. u32 nav_id, u32 src_thread, u32 dst_thread)
  2053. {
  2054. struct ti_sci_msg_hdr *resp;
  2055. struct ti_sci_msg_psil_pair req;
  2056. struct ti_sci_xfer *xfer;
  2057. struct ti_sci_info *info;
  2058. int ret = 0;
  2059. if (IS_ERR(handle))
  2060. return PTR_ERR(handle);
  2061. if (!handle)
  2062. return -EINVAL;
  2063. info = handle_to_ti_sci_info(handle);
  2064. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_PSIL_PAIR,
  2065. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2066. (u32 *)&req, sizeof(req), sizeof(*resp));
  2067. if (IS_ERR(xfer)) {
  2068. ret = PTR_ERR(xfer);
  2069. dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret);
  2070. return ret;
  2071. }
  2072. req.nav_id = nav_id;
  2073. req.src_thread = src_thread;
  2074. req.dst_thread = dst_thread;
  2075. ret = ti_sci_do_xfer(info, xfer);
  2076. if (ret) {
  2077. dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret);
  2078. goto fail;
  2079. }
  2080. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  2081. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  2082. fail:
  2083. dev_dbg(info->dev, "RM_PSIL: nav: %u link pair %u->%u ret:%u\n",
  2084. nav_id, src_thread, dst_thread, ret);
  2085. return ret;
  2086. }
  2087. static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle,
  2088. u32 nav_id, u32 src_thread, u32 dst_thread)
  2089. {
  2090. struct ti_sci_msg_hdr *resp;
  2091. struct ti_sci_msg_psil_unpair req;
  2092. struct ti_sci_xfer *xfer;
  2093. struct ti_sci_info *info;
  2094. int ret = 0;
  2095. if (IS_ERR(handle))
  2096. return PTR_ERR(handle);
  2097. if (!handle)
  2098. return -EINVAL;
  2099. info = handle_to_ti_sci_info(handle);
  2100. xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_PSIL_UNPAIR,
  2101. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2102. (u32 *)&req, sizeof(req), sizeof(*resp));
  2103. if (IS_ERR(xfer)) {
  2104. ret = PTR_ERR(xfer);
  2105. dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret);
  2106. return ret;
  2107. }
  2108. req.nav_id = nav_id;
  2109. req.src_thread = src_thread;
  2110. req.dst_thread = dst_thread;
  2111. ret = ti_sci_do_xfer(info, xfer);
  2112. if (ret) {
  2113. dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret);
  2114. goto fail;
  2115. }
  2116. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  2117. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  2118. fail:
  2119. dev_dbg(info->dev, "RM_PSIL: link unpair %u->%u ret:%u\n",
  2120. src_thread, dst_thread, ret);
  2121. return ret;
  2122. }
  2123. static int ti_sci_cmd_rm_udmap_tx_ch_cfg(
  2124. const struct ti_sci_handle *handle,
  2125. const struct ti_sci_msg_rm_udmap_tx_ch_cfg *params)
  2126. {
  2127. struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *resp;
  2128. struct ti_sci_msg_rm_udmap_tx_ch_cfg_req req;
  2129. struct ti_sci_xfer *xfer;
  2130. struct ti_sci_info *info;
  2131. int ret = 0;
  2132. if (IS_ERR(handle))
  2133. return PTR_ERR(handle);
  2134. if (!handle)
  2135. return -EINVAL;
  2136. info = handle_to_ti_sci_info(handle);
  2137. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_RM_UDMAP_TX_CH_CFG,
  2138. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2139. (u32 *)&req, sizeof(req), sizeof(*resp));
  2140. if (IS_ERR(xfer)) {
  2141. ret = PTR_ERR(xfer);
  2142. dev_err(info->dev, "Message TX_CH_CFG alloc failed(%d)\n", ret);
  2143. return ret;
  2144. }
  2145. req.valid_params = params->valid_params;
  2146. req.nav_id = params->nav_id;
  2147. req.index = params->index;
  2148. req.tx_pause_on_err = params->tx_pause_on_err;
  2149. req.tx_filt_einfo = params->tx_filt_einfo;
  2150. req.tx_filt_pswords = params->tx_filt_pswords;
  2151. req.tx_atype = params->tx_atype;
  2152. req.tx_chan_type = params->tx_chan_type;
  2153. req.tx_supr_tdpkt = params->tx_supr_tdpkt;
  2154. req.tx_fetch_size = params->tx_fetch_size;
  2155. req.tx_credit_count = params->tx_credit_count;
  2156. req.txcq_qnum = params->txcq_qnum;
  2157. req.tx_priority = params->tx_priority;
  2158. req.tx_qos = params->tx_qos;
  2159. req.tx_orderid = params->tx_orderid;
  2160. req.fdepth = params->fdepth;
  2161. req.tx_sched_priority = params->tx_sched_priority;
  2162. req.tx_burst_size = params->tx_burst_size;
  2163. req.tx_tdtype = params->tx_tdtype;
  2164. req.extended_ch_type = params->extended_ch_type;
  2165. ret = ti_sci_do_xfer(info, xfer);
  2166. if (ret) {
  2167. dev_err(info->dev, "Mbox send TX_CH_CFG fail %d\n", ret);
  2168. goto fail;
  2169. }
  2170. resp =
  2171. (struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *)xfer->tx_message.buf;
  2172. ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
  2173. fail:
  2174. dev_dbg(info->dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret);
  2175. return ret;
  2176. }
  2177. static int ti_sci_cmd_rm_udmap_rx_ch_cfg(
  2178. const struct ti_sci_handle *handle,
  2179. const struct ti_sci_msg_rm_udmap_rx_ch_cfg *params)
  2180. {
  2181. struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *resp;
  2182. struct ti_sci_msg_rm_udmap_rx_ch_cfg_req req;
  2183. struct ti_sci_xfer *xfer;
  2184. struct ti_sci_info *info;
  2185. int ret = 0;
  2186. if (IS_ERR(handle))
  2187. return PTR_ERR(handle);
  2188. if (!handle)
  2189. return -EINVAL;
  2190. info = handle_to_ti_sci_info(handle);
  2191. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_RM_UDMAP_RX_CH_CFG,
  2192. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2193. (u32 *)&req, sizeof(req), sizeof(*resp));
  2194. if (IS_ERR(xfer)) {
  2195. ret = PTR_ERR(xfer);
  2196. dev_err(info->dev, "Message RX_CH_CFG alloc failed(%d)\n", ret);
  2197. return ret;
  2198. }
  2199. req.valid_params = params->valid_params;
  2200. req.nav_id = params->nav_id;
  2201. req.index = params->index;
  2202. req.rx_fetch_size = params->rx_fetch_size;
  2203. req.rxcq_qnum = params->rxcq_qnum;
  2204. req.rx_priority = params->rx_priority;
  2205. req.rx_qos = params->rx_qos;
  2206. req.rx_orderid = params->rx_orderid;
  2207. req.rx_sched_priority = params->rx_sched_priority;
  2208. req.flowid_start = params->flowid_start;
  2209. req.flowid_cnt = params->flowid_cnt;
  2210. req.rx_pause_on_err = params->rx_pause_on_err;
  2211. req.rx_atype = params->rx_atype;
  2212. req.rx_chan_type = params->rx_chan_type;
  2213. req.rx_ignore_short = params->rx_ignore_short;
  2214. req.rx_ignore_long = params->rx_ignore_long;
  2215. ret = ti_sci_do_xfer(info, xfer);
  2216. if (ret) {
  2217. dev_err(info->dev, "Mbox send RX_CH_CFG fail %d\n", ret);
  2218. goto fail;
  2219. }
  2220. resp =
  2221. (struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *)xfer->tx_message.buf;
  2222. ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
  2223. fail:
  2224. dev_dbg(info->dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret);
  2225. return ret;
  2226. }
  2227. static int ti_sci_cmd_rm_udmap_rx_flow_cfg(
  2228. const struct ti_sci_handle *handle,
  2229. const struct ti_sci_msg_rm_udmap_flow_cfg *params)
  2230. {
  2231. struct ti_sci_msg_rm_udmap_flow_cfg_resp *resp;
  2232. struct ti_sci_msg_rm_udmap_flow_cfg_req req;
  2233. struct ti_sci_xfer *xfer;
  2234. struct ti_sci_info *info;
  2235. int ret = 0;
  2236. if (IS_ERR(handle))
  2237. return PTR_ERR(handle);
  2238. if (!handle)
  2239. return -EINVAL;
  2240. info = handle_to_ti_sci_info(handle);
  2241. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_RM_UDMAP_FLOW_CFG,
  2242. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2243. (u32 *)&req, sizeof(req), sizeof(*resp));
  2244. if (IS_ERR(xfer)) {
  2245. ret = PTR_ERR(xfer);
  2246. dev_err(info->dev, "RX_FL_CFG: Message alloc failed(%d)\n",
  2247. ret);
  2248. return ret;
  2249. }
  2250. req.valid_params = params->valid_params;
  2251. req.nav_id = params->nav_id;
  2252. req.flow_index = params->flow_index;
  2253. req.rx_einfo_present = params->rx_einfo_present;
  2254. req.rx_psinfo_present = params->rx_psinfo_present;
  2255. req.rx_error_handling = params->rx_error_handling;
  2256. req.rx_desc_type = params->rx_desc_type;
  2257. req.rx_sop_offset = params->rx_sop_offset;
  2258. req.rx_dest_qnum = params->rx_dest_qnum;
  2259. req.rx_src_tag_hi = params->rx_src_tag_hi;
  2260. req.rx_src_tag_lo = params->rx_src_tag_lo;
  2261. req.rx_dest_tag_hi = params->rx_dest_tag_hi;
  2262. req.rx_dest_tag_lo = params->rx_dest_tag_lo;
  2263. req.rx_src_tag_hi_sel = params->rx_src_tag_hi_sel;
  2264. req.rx_src_tag_lo_sel = params->rx_src_tag_lo_sel;
  2265. req.rx_dest_tag_hi_sel = params->rx_dest_tag_hi_sel;
  2266. req.rx_dest_tag_lo_sel = params->rx_dest_tag_lo_sel;
  2267. req.rx_fdq0_sz0_qnum = params->rx_fdq0_sz0_qnum;
  2268. req.rx_fdq1_qnum = params->rx_fdq1_qnum;
  2269. req.rx_fdq2_qnum = params->rx_fdq2_qnum;
  2270. req.rx_fdq3_qnum = params->rx_fdq3_qnum;
  2271. req.rx_ps_location = params->rx_ps_location;
  2272. ret = ti_sci_do_xfer(info, xfer);
  2273. if (ret) {
  2274. dev_err(info->dev, "RX_FL_CFG: Mbox send fail %d\n", ret);
  2275. goto fail;
  2276. }
  2277. resp =
  2278. (struct ti_sci_msg_rm_udmap_flow_cfg_resp *)xfer->tx_message.buf;
  2279. ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
  2280. fail:
  2281. dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret);
  2282. return ret;
  2283. }
  2284. /**
  2285. * ti_sci_cmd_set_fwl_region() - Request for configuring a firewall region
  2286. * @handle: pointer to TI SCI handle
  2287. * @region: region configuration parameters
  2288. *
  2289. * Return: 0 if all went well, else returns appropriate error value.
  2290. */
  2291. static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle,
  2292. const struct ti_sci_msg_fwl_region *region)
  2293. {
  2294. struct ti_sci_msg_fwl_set_firewall_region_req req;
  2295. struct ti_sci_msg_hdr *resp;
  2296. struct ti_sci_info *info;
  2297. struct ti_sci_xfer *xfer;
  2298. int ret = 0;
  2299. if (IS_ERR(handle))
  2300. return PTR_ERR(handle);
  2301. if (!handle)
  2302. return -EINVAL;
  2303. info = handle_to_ti_sci_info(handle);
  2304. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_SET,
  2305. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2306. (u32 *)&req, sizeof(req), sizeof(*resp));
  2307. if (IS_ERR(xfer)) {
  2308. ret = PTR_ERR(xfer);
  2309. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  2310. return ret;
  2311. }
  2312. req.fwl_id = region->fwl_id;
  2313. req.region = region->region;
  2314. req.n_permission_regs = region->n_permission_regs;
  2315. req.control = region->control;
  2316. req.permissions[0] = region->permissions[0];
  2317. req.permissions[1] = region->permissions[1];
  2318. req.permissions[2] = region->permissions[2];
  2319. req.start_address = region->start_address;
  2320. req.end_address = region->end_address;
  2321. ret = ti_sci_do_xfer(info, xfer);
  2322. if (ret) {
  2323. dev_err(info->dev, "Mbox send fail %d\n", ret);
  2324. return ret;
  2325. }
  2326. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  2327. if (!ti_sci_is_response_ack(resp))
  2328. return -ENODEV;
  2329. return 0;
  2330. }
  2331. /**
  2332. * ti_sci_cmd_get_fwl_region() - Request for getting a firewall region
  2333. * @handle: pointer to TI SCI handle
  2334. * @region: region configuration parameters
  2335. *
  2336. * Return: 0 if all went well, else returns appropriate error value.
  2337. */
  2338. static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle,
  2339. struct ti_sci_msg_fwl_region *region)
  2340. {
  2341. struct ti_sci_msg_fwl_get_firewall_region_req req;
  2342. struct ti_sci_msg_fwl_get_firewall_region_resp *resp;
  2343. struct ti_sci_info *info;
  2344. struct ti_sci_xfer *xfer;
  2345. int ret = 0;
  2346. if (IS_ERR(handle))
  2347. return PTR_ERR(handle);
  2348. if (!handle)
  2349. return -EINVAL;
  2350. info = handle_to_ti_sci_info(handle);
  2351. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_GET,
  2352. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2353. (u32 *)&req, sizeof(req), sizeof(*resp));
  2354. if (IS_ERR(xfer)) {
  2355. ret = PTR_ERR(xfer);
  2356. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  2357. return ret;
  2358. }
  2359. req.fwl_id = region->fwl_id;
  2360. req.region = region->region;
  2361. req.n_permission_regs = region->n_permission_regs;
  2362. ret = ti_sci_do_xfer(info, xfer);
  2363. if (ret) {
  2364. dev_err(info->dev, "Mbox send fail %d\n", ret);
  2365. return ret;
  2366. }
  2367. resp = (struct ti_sci_msg_fwl_get_firewall_region_resp *)xfer->tx_message.buf;
  2368. if (!ti_sci_is_response_ack(resp))
  2369. return -ENODEV;
  2370. region->fwl_id = resp->fwl_id;
  2371. region->region = resp->region;
  2372. region->n_permission_regs = resp->n_permission_regs;
  2373. region->control = resp->control;
  2374. region->permissions[0] = resp->permissions[0];
  2375. region->permissions[1] = resp->permissions[1];
  2376. region->permissions[2] = resp->permissions[2];
  2377. region->start_address = resp->start_address;
  2378. region->end_address = resp->end_address;
  2379. return 0;
  2380. }
  2381. /**
  2382. * ti_sci_cmd_change_fwl_owner() - Request for changing a firewall owner
  2383. * @handle: pointer to TI SCI handle
  2384. * @region: region configuration parameters
  2385. *
  2386. * Return: 0 if all went well, else returns appropriate error value.
  2387. */
  2388. static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle,
  2389. struct ti_sci_msg_fwl_owner *owner)
  2390. {
  2391. struct ti_sci_msg_fwl_change_owner_info_req req;
  2392. struct ti_sci_msg_fwl_change_owner_info_resp *resp;
  2393. struct ti_sci_info *info;
  2394. struct ti_sci_xfer *xfer;
  2395. int ret = 0;
  2396. if (IS_ERR(handle))
  2397. return PTR_ERR(handle);
  2398. if (!handle)
  2399. return -EINVAL;
  2400. info = handle_to_ti_sci_info(handle);
  2401. xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_CHANGE_OWNER,
  2402. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2403. (u32 *)&req, sizeof(req), sizeof(*resp));
  2404. if (IS_ERR(xfer)) {
  2405. ret = PTR_ERR(xfer);
  2406. dev_err(info->dev, "Message alloc failed(%d)\n", ret);
  2407. return ret;
  2408. }
  2409. req.fwl_id = owner->fwl_id;
  2410. req.region = owner->region;
  2411. req.owner_index = owner->owner_index;
  2412. ret = ti_sci_do_xfer(info, xfer);
  2413. if (ret) {
  2414. dev_err(info->dev, "Mbox send fail %d\n", ret);
  2415. return ret;
  2416. }
  2417. resp = (struct ti_sci_msg_fwl_change_owner_info_resp *)xfer->tx_message.buf;
  2418. if (!ti_sci_is_response_ack(resp))
  2419. return -ENODEV;
  2420. owner->fwl_id = resp->fwl_id;
  2421. owner->region = resp->region;
  2422. owner->owner_index = resp->owner_index;
  2423. owner->owner_privid = resp->owner_privid;
  2424. owner->owner_permission_bits = resp->owner_permission_bits;
  2425. return ret;
  2426. }
  2427. /*
  2428. * ti_sci_setup_ops() - Setup the operations structures
  2429. * @info: pointer to TISCI pointer
  2430. */
  2431. static void ti_sci_setup_ops(struct ti_sci_info *info)
  2432. {
  2433. struct ti_sci_ops *ops = &info->handle.ops;
  2434. struct ti_sci_board_ops *bops = &ops->board_ops;
  2435. struct ti_sci_dev_ops *dops = &ops->dev_ops;
  2436. struct ti_sci_clk_ops *cops = &ops->clk_ops;
  2437. struct ti_sci_core_ops *core_ops = &ops->core_ops;
  2438. struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
  2439. struct ti_sci_proc_ops *pops = &ops->proc_ops;
  2440. struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops;
  2441. struct ti_sci_rm_psil_ops *psilops = &ops->rm_psil_ops;
  2442. struct ti_sci_rm_udmap_ops *udmap_ops = &ops->rm_udmap_ops;
  2443. struct ti_sci_fwl_ops *fwl_ops = &ops->fwl_ops;
  2444. bops->board_config = ti_sci_cmd_set_board_config;
  2445. bops->board_config_rm = ti_sci_cmd_set_board_config_rm;
  2446. bops->board_config_security = ti_sci_cmd_set_board_config_security;
  2447. bops->board_config_pm = ti_sci_cmd_set_board_config_pm;
  2448. dops->get_device = ti_sci_cmd_get_device;
  2449. dops->get_device_exclusive = ti_sci_cmd_get_device_exclusive;
  2450. dops->idle_device = ti_sci_cmd_idle_device;
  2451. dops->idle_device_exclusive = ti_sci_cmd_idle_device_exclusive;
  2452. dops->put_device = ti_sci_cmd_put_device;
  2453. dops->is_valid = ti_sci_cmd_dev_is_valid;
  2454. dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt;
  2455. dops->is_idle = ti_sci_cmd_dev_is_idle;
  2456. dops->is_stop = ti_sci_cmd_dev_is_stop;
  2457. dops->is_on = ti_sci_cmd_dev_is_on;
  2458. dops->is_transitioning = ti_sci_cmd_dev_is_trans;
  2459. dops->set_device_resets = ti_sci_cmd_set_device_resets;
  2460. dops->get_device_resets = ti_sci_cmd_get_device_resets;
  2461. dops->release_exclusive_devices = ti_sci_cmd_release_exclusive_devices;
  2462. cops->get_clock = ti_sci_cmd_get_clock;
  2463. cops->idle_clock = ti_sci_cmd_idle_clock;
  2464. cops->put_clock = ti_sci_cmd_put_clock;
  2465. cops->is_auto = ti_sci_cmd_clk_is_auto;
  2466. cops->is_on = ti_sci_cmd_clk_is_on;
  2467. cops->is_off = ti_sci_cmd_clk_is_off;
  2468. cops->set_parent = ti_sci_cmd_clk_set_parent;
  2469. cops->get_parent = ti_sci_cmd_clk_get_parent;
  2470. cops->get_num_parents = ti_sci_cmd_clk_get_num_parents;
  2471. cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
  2472. cops->set_freq = ti_sci_cmd_clk_set_freq;
  2473. cops->get_freq = ti_sci_cmd_clk_get_freq;
  2474. core_ops->reboot_device = ti_sci_cmd_core_reboot;
  2475. core_ops->query_msmc = ti_sci_cmd_query_msmc;
  2476. rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
  2477. rm_core_ops->get_range_from_shost =
  2478. ti_sci_cmd_get_resource_range_from_shost;
  2479. pops->proc_request = ti_sci_cmd_proc_request;
  2480. pops->proc_release = ti_sci_cmd_proc_release;
  2481. pops->proc_handover = ti_sci_cmd_proc_handover;
  2482. pops->set_proc_boot_cfg = ti_sci_cmd_set_proc_boot_cfg;
  2483. pops->set_proc_boot_ctrl = ti_sci_cmd_set_proc_boot_ctrl;
  2484. pops->proc_auth_boot_image = ti_sci_cmd_proc_auth_boot_image;
  2485. pops->get_proc_boot_status = ti_sci_cmd_get_proc_boot_status;
  2486. pops->proc_shutdown_no_wait = ti_sci_cmd_proc_shutdown_no_wait;
  2487. rops->config = ti_sci_cmd_ring_config;
  2488. psilops->pair = ti_sci_cmd_rm_psil_pair;
  2489. psilops->unpair = ti_sci_cmd_rm_psil_unpair;
  2490. udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg;
  2491. udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg;
  2492. udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg;
  2493. fwl_ops->set_fwl_region = ti_sci_cmd_set_fwl_region;
  2494. fwl_ops->get_fwl_region = ti_sci_cmd_get_fwl_region;
  2495. fwl_ops->change_fwl_owner = ti_sci_cmd_change_fwl_owner;
  2496. }
  2497. /**
  2498. * ti_sci_get_handle_from_sysfw() - Get the TI SCI handle of the SYSFW
  2499. * @dev: Pointer to the SYSFW device
  2500. *
  2501. * Return: pointer to handle if successful, else EINVAL if invalid conditions
  2502. * are encountered.
  2503. */
  2504. const
  2505. struct ti_sci_handle *ti_sci_get_handle_from_sysfw(struct udevice *sci_dev)
  2506. {
  2507. if (!sci_dev)
  2508. return ERR_PTR(-EINVAL);
  2509. struct ti_sci_info *info = dev_get_priv(sci_dev);
  2510. if (!info)
  2511. return ERR_PTR(-EINVAL);
  2512. struct ti_sci_handle *handle = &info->handle;
  2513. if (!handle)
  2514. return ERR_PTR(-EINVAL);
  2515. return handle;
  2516. }
  2517. /**
  2518. * ti_sci_get_handle() - Get the TI SCI handle for a device
  2519. * @dev: Pointer to device for which we want SCI handle
  2520. *
  2521. * Return: pointer to handle if successful, else EINVAL if invalid conditions
  2522. * are encountered.
  2523. */
  2524. const struct ti_sci_handle *ti_sci_get_handle(struct udevice *dev)
  2525. {
  2526. if (!dev)
  2527. return ERR_PTR(-EINVAL);
  2528. struct udevice *sci_dev = dev_get_parent(dev);
  2529. return ti_sci_get_handle_from_sysfw(sci_dev);
  2530. }
  2531. /**
  2532. * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle
  2533. * @dev: device node
  2534. * @propname: property name containing phandle on TISCI node
  2535. *
  2536. * Return: pointer to handle if successful, else appropriate error value.
  2537. */
  2538. const struct ti_sci_handle *ti_sci_get_by_phandle(struct udevice *dev,
  2539. const char *property)
  2540. {
  2541. struct ti_sci_info *entry, *info = NULL;
  2542. u32 phandle, err;
  2543. ofnode node;
  2544. err = ofnode_read_u32(dev_ofnode(dev), property, &phandle);
  2545. if (err)
  2546. return ERR_PTR(err);
  2547. node = ofnode_get_by_phandle(phandle);
  2548. if (!ofnode_valid(node))
  2549. return ERR_PTR(-EINVAL);
  2550. list_for_each_entry(entry, &ti_sci_list, list)
  2551. if (ofnode_equal(dev_ofnode(entry->dev), node)) {
  2552. info = entry;
  2553. break;
  2554. }
  2555. if (!info)
  2556. return ERR_PTR(-ENODEV);
  2557. return &info->handle;
  2558. }
  2559. /**
  2560. * ti_sci_of_to_info() - generate private data from device tree
  2561. * @dev: corresponding system controller interface device
  2562. * @info: pointer to driver specific private data
  2563. *
  2564. * Return: 0 if all goes good, else appropriate error message.
  2565. */
  2566. static int ti_sci_of_to_info(struct udevice *dev, struct ti_sci_info *info)
  2567. {
  2568. int ret;
  2569. ret = mbox_get_by_name(dev, "tx", &info->chan_tx);
  2570. if (ret) {
  2571. dev_err(dev, "%s: Acquiring Tx channel failed. ret = %d\n",
  2572. __func__, ret);
  2573. return ret;
  2574. }
  2575. ret = mbox_get_by_name(dev, "rx", &info->chan_rx);
  2576. if (ret) {
  2577. dev_err(dev, "%s: Acquiring Rx channel failed. ret = %d\n",
  2578. __func__, ret);
  2579. return ret;
  2580. }
  2581. /* Notify channel is optional. Enable only if populated */
  2582. ret = mbox_get_by_name(dev, "notify", &info->chan_notify);
  2583. if (ret) {
  2584. dev_dbg(dev, "%s: Acquiring notify channel failed. ret = %d\n",
  2585. __func__, ret);
  2586. }
  2587. info->host_id = dev_read_u32_default(dev, "ti,host-id",
  2588. info->desc->default_host_id);
  2589. info->is_secure = dev_read_bool(dev, "ti,secure-host");
  2590. return 0;
  2591. }
  2592. /**
  2593. * ti_sci_probe() - Basic probe
  2594. * @dev: corresponding system controller interface device
  2595. *
  2596. * Return: 0 if all goes good, else appropriate error message.
  2597. */
  2598. static int ti_sci_probe(struct udevice *dev)
  2599. {
  2600. struct ti_sci_info *info;
  2601. int ret;
  2602. debug("%s(dev=%p)\n", __func__, dev);
  2603. info = dev_get_priv(dev);
  2604. info->desc = (void *)dev_get_driver_data(dev);
  2605. ret = ti_sci_of_to_info(dev, info);
  2606. if (ret) {
  2607. dev_err(dev, "%s: Probe failed with error %d\n", __func__, ret);
  2608. return ret;
  2609. }
  2610. info->dev = dev;
  2611. info->seq = 0xA;
  2612. list_add_tail(&info->list, &ti_sci_list);
  2613. ti_sci_setup_ops(info);
  2614. ret = ti_sci_cmd_get_revision(&info->handle);
  2615. INIT_LIST_HEAD(&info->dev_list);
  2616. return ret;
  2617. }
  2618. /**
  2619. * ti_sci_dm_probe() - Basic probe for DM to TIFS SCI
  2620. * @dev: corresponding system controller interface device
  2621. *
  2622. * Return: 0 if all goes good, else appropriate error message.
  2623. */
  2624. static __maybe_unused int ti_sci_dm_probe(struct udevice *dev)
  2625. {
  2626. struct ti_sci_rm_core_ops *rm_core_ops;
  2627. struct ti_sci_rm_udmap_ops *udmap_ops;
  2628. struct ti_sci_rm_ringacc_ops *rops;
  2629. struct ti_sci_rm_psil_ops *psilops;
  2630. struct ti_sci_ops *ops;
  2631. struct ti_sci_info *info;
  2632. int ret;
  2633. debug("%s(dev=%p)\n", __func__, dev);
  2634. info = dev_get_priv(dev);
  2635. info->desc = (void *)dev_get_driver_data(dev);
  2636. ret = ti_sci_of_to_info(dev, info);
  2637. if (ret) {
  2638. dev_err(dev, "%s: Probe failed with error %d\n", __func__, ret);
  2639. return ret;
  2640. }
  2641. info->dev = dev;
  2642. info->seq = 0xA;
  2643. list_add_tail(&info->list, &ti_sci_list);
  2644. ops = &info->handle.ops;
  2645. rm_core_ops = &ops->rm_core_ops;
  2646. rm_core_ops->get_range = ti_sci_cmd_get_resource_range_static;
  2647. rops = &ops->rm_ring_ops;
  2648. rops->config = ti_sci_cmd_ring_config;
  2649. psilops = &ops->rm_psil_ops;
  2650. psilops->pair = ti_sci_cmd_rm_psil_pair;
  2651. psilops->unpair = ti_sci_cmd_rm_psil_unpair;
  2652. udmap_ops = &ops->rm_udmap_ops;
  2653. udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg;
  2654. udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg;
  2655. udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg;
  2656. return ret;
  2657. }
  2658. /*
  2659. * ti_sci_get_free_resource() - Get a free resource from TISCI resource.
  2660. * @res: Pointer to the TISCI resource
  2661. *
  2662. * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL.
  2663. */
  2664. u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
  2665. {
  2666. u16 set, free_bit;
  2667. for (set = 0; set < res->sets; set++) {
  2668. free_bit = find_first_zero_bit(res->desc[set].res_map,
  2669. res->desc[set].num);
  2670. if (free_bit != res->desc[set].num) {
  2671. set_bit(free_bit, res->desc[set].res_map);
  2672. return res->desc[set].start + free_bit;
  2673. }
  2674. }
  2675. return TI_SCI_RESOURCE_NULL;
  2676. }
  2677. /**
  2678. * ti_sci_release_resource() - Release a resource from TISCI resource.
  2679. * @res: Pointer to the TISCI resource
  2680. */
  2681. void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
  2682. {
  2683. u16 set;
  2684. for (set = 0; set < res->sets; set++) {
  2685. if (res->desc[set].start <= id &&
  2686. (res->desc[set].num + res->desc[set].start) > id)
  2687. clear_bit(id - res->desc[set].start,
  2688. res->desc[set].res_map);
  2689. }
  2690. }
  2691. /**
  2692. * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device
  2693. * @handle: TISCI handle
  2694. * @dev: Device pointer to which the resource is assigned
  2695. * @of_prop: property name by which the resource are represented
  2696. *
  2697. * Note: This function expects of_prop to be in the form of tuples
  2698. * <type, subtype>. Allocates and initializes ti_sci_resource structure
  2699. * for each of_prop. Client driver can directly call
  2700. * ti_sci_(get_free, release)_resource apis for handling the resource.
  2701. *
  2702. * Return: Pointer to ti_sci_resource if all went well else appropriate
  2703. * error pointer.
  2704. */
  2705. struct ti_sci_resource *
  2706. devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
  2707. struct udevice *dev, u32 dev_id, char *of_prop)
  2708. {
  2709. u32 resource_subtype;
  2710. struct ti_sci_resource *res;
  2711. bool valid_set = false;
  2712. int sets, i, ret;
  2713. u32 *temp;
  2714. res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
  2715. if (!res)
  2716. return ERR_PTR(-ENOMEM);
  2717. sets = dev_read_size(dev, of_prop);
  2718. if (sets < 0) {
  2719. dev_err(dev, "%s resource type ids not available\n", of_prop);
  2720. return ERR_PTR(sets);
  2721. }
  2722. temp = malloc(sets);
  2723. sets /= sizeof(u32);
  2724. res->sets = sets;
  2725. res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
  2726. GFP_KERNEL);
  2727. if (!res->desc)
  2728. return ERR_PTR(-ENOMEM);
  2729. ret = dev_read_u32_array(dev, of_prop, temp, res->sets);
  2730. if (ret)
  2731. return ERR_PTR(-EINVAL);
  2732. for (i = 0; i < res->sets; i++) {
  2733. resource_subtype = temp[i];
  2734. ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
  2735. resource_subtype,
  2736. &res->desc[i].start,
  2737. &res->desc[i].num);
  2738. if (ret) {
  2739. dev_dbg(dev, "type %d subtype %d not allocated for host %d\n",
  2740. dev_id, resource_subtype,
  2741. handle_to_ti_sci_info(handle)->host_id);
  2742. res->desc[i].start = 0;
  2743. res->desc[i].num = 0;
  2744. continue;
  2745. }
  2746. valid_set = true;
  2747. dev_dbg(dev, "res type = %d, subtype = %d, start = %d, num = %d\n",
  2748. dev_id, resource_subtype, res->desc[i].start,
  2749. res->desc[i].num);
  2750. res->desc[i].res_map =
  2751. devm_kzalloc(dev, BITS_TO_LONGS(res->desc[i].num) *
  2752. sizeof(*res->desc[i].res_map), GFP_KERNEL);
  2753. if (!res->desc[i].res_map)
  2754. return ERR_PTR(-ENOMEM);
  2755. }
  2756. if (valid_set)
  2757. return res;
  2758. return ERR_PTR(-EINVAL);
  2759. }
  2760. /* Description for K2G */
  2761. static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
  2762. .default_host_id = 2,
  2763. /* Conservative duration */
  2764. .max_rx_timeout_ms = 10000,
  2765. /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
  2766. .max_msgs = 20,
  2767. .max_msg_size = 64,
  2768. };
  2769. /* Description for AM654 */
  2770. static const struct ti_sci_desc ti_sci_pmmc_am654_desc = {
  2771. .default_host_id = 12,
  2772. /* Conservative duration */
  2773. .max_rx_timeout_ms = 10000,
  2774. /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
  2775. .max_msgs = 20,
  2776. .max_msg_size = 60,
  2777. };
  2778. /* Description for J721e DM to DMSC communication */
  2779. static const struct ti_sci_desc ti_sci_dm_j721e_desc = {
  2780. .default_host_id = 3,
  2781. .max_rx_timeout_ms = 10000,
  2782. .max_msgs = 20,
  2783. .max_msg_size = 60,
  2784. };
  2785. static const struct udevice_id ti_sci_ids[] = {
  2786. {
  2787. .compatible = "ti,k2g-sci",
  2788. .data = (ulong)&ti_sci_pmmc_k2g_desc
  2789. },
  2790. {
  2791. .compatible = "ti,am654-sci",
  2792. .data = (ulong)&ti_sci_pmmc_am654_desc
  2793. },
  2794. { /* Sentinel */ },
  2795. };
  2796. static __maybe_unused const struct udevice_id ti_sci_dm_ids[] = {
  2797. {
  2798. .compatible = "ti,j721e-dm-sci",
  2799. .data = (ulong)&ti_sci_dm_j721e_desc
  2800. },
  2801. { /* Sentinel */ },
  2802. };
  2803. U_BOOT_DRIVER(ti_sci) = {
  2804. .name = "ti_sci",
  2805. .id = UCLASS_FIRMWARE,
  2806. .of_match = ti_sci_ids,
  2807. .probe = ti_sci_probe,
  2808. .priv_auto = sizeof(struct ti_sci_info),
  2809. };
  2810. #if IS_ENABLED(CONFIG_K3_DM_FW)
  2811. U_BOOT_DRIVER(ti_sci_dm) = {
  2812. .name = "ti_sci_dm",
  2813. .id = UCLASS_FIRMWARE,
  2814. .of_match = ti_sci_dm_ids,
  2815. .probe = ti_sci_dm_probe,
  2816. .priv_auto = sizeof(struct ti_sci_info),
  2817. };
  2818. #endif