ti_sci.c 114 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Texas Instruments System Control Interface Protocol Driver
  4. *
  5. * Copyright (C) 2015-2025 Texas Instruments Incorporated - https://www.ti.com/
  6. * Nishanth Menon
  7. */
  8. #define pr_fmt(fmt) "%s: " fmt, __func__
  9. #include <linux/bitmap.h>
  10. #include <linux/cpu.h>
  11. #include <linux/debugfs.h>
  12. #include <linux/export.h>
  13. #include <linux/io.h>
  14. #include <linux/iopoll.h>
  15. #include <linux/kernel.h>
  16. #include <linux/mailbox_client.h>
  17. #include <linux/module.h>
  18. #include <linux/of.h>
  19. #include <linux/of_platform.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/pm_qos.h>
  22. #include <linux/property.h>
  23. #include <linux/semaphore.h>
  24. #include <linux/slab.h>
  25. #include <linux/soc/ti/ti-msgmgr.h>
  26. #include <linux/soc/ti/ti_sci_protocol.h>
  27. #include <linux/suspend.h>
  28. #include <linux/sys_soc.h>
  29. #include <linux/reboot.h>
  30. #include "ti_sci.h"
  31. /* List of all TI SCI devices active in system */
  32. static LIST_HEAD(ti_sci_list);
  33. /* Protection for the entire list */
  34. static DEFINE_MUTEX(ti_sci_list_mutex);
  35. /**
  36. * struct ti_sci_xfer - Structure representing a message flow
  37. * @tx_message: Transmit message
  38. * @rx_len: Receive message length
  39. * @xfer_buf: Preallocated buffer to store receive message
  40. * Since we work with request-ACK protocol, we can
  41. * reuse the same buffer for the rx path as we
  42. * use for the tx path.
  43. * @done: completion event
  44. */
  45. struct ti_sci_xfer {
  46. struct ti_msgmgr_message tx_message;
  47. u8 rx_len;
  48. u8 *xfer_buf;
  49. struct completion done;
  50. };
  51. /**
  52. * struct ti_sci_xfers_info - Structure to manage transfer information
  53. * @sem_xfer_count: Counting Semaphore for managing max simultaneous
  54. * Messages.
  55. * @xfer_block: Preallocated Message array
  56. * @xfer_alloc_table: Bitmap table for allocated messages.
  57. * Index of this bitmap table is also used for message
  58. * sequence identifier.
  59. * @xfer_lock: Protection for message allocation
  60. */
  61. struct ti_sci_xfers_info {
  62. struct semaphore sem_xfer_count;
  63. struct ti_sci_xfer *xfer_block;
  64. unsigned long *xfer_alloc_table;
  65. /* protect transfer allocation */
  66. spinlock_t xfer_lock;
  67. };
  68. /**
  69. * struct ti_sci_desc - Description of SoC integration
  70. * @default_host_id: Host identifier representing the compute entity
  71. * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
  72. * @max_msgs: Maximum number of messages that can be pending
  73. * simultaneously in the system
  74. * @max_msg_size: Maximum size of data per message that can be handled.
  75. */
  76. struct ti_sci_desc {
  77. u8 default_host_id;
  78. int max_rx_timeout_ms;
  79. int max_msgs;
  80. int max_msg_size;
  81. };
  82. /**
  83. * struct ti_sci_info - Structure representing a TI SCI instance
  84. * @dev: Device pointer
  85. * @desc: SoC description for this instance
  86. * @d: Debugfs file entry
  87. * @debug_region: Memory region where the debug message are available
  88. * @debug_region_size: Debug region size
  89. * @debug_buffer: Buffer allocated to copy debug messages.
  90. * @handle: Instance of TI SCI handle to send to clients.
  91. * @cl: Mailbox Client
  92. * @chan_tx: Transmit mailbox channel
  93. * @chan_rx: Receive mailbox channel
  94. * @minfo: Message info
  95. * @node: list head
  96. * @host_id: Host ID
  97. * @fw_caps: FW/SoC low power capabilities
  98. * @users: Number of users of this instance
  99. */
  100. struct ti_sci_info {
  101. struct device *dev;
  102. const struct ti_sci_desc *desc;
  103. struct dentry *d;
  104. void __iomem *debug_region;
  105. char *debug_buffer;
  106. size_t debug_region_size;
  107. struct ti_sci_handle handle;
  108. struct mbox_client cl;
  109. struct mbox_chan *chan_tx;
  110. struct mbox_chan *chan_rx;
  111. struct ti_sci_xfers_info minfo;
  112. struct list_head node;
  113. u8 host_id;
  114. u64 fw_caps;
  115. /* protected by ti_sci_list_mutex */
  116. int users;
  117. };
  118. #define cl_to_ti_sci_info(c) container_of(c, struct ti_sci_info, cl)
  119. #define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle)
  120. #ifdef CONFIG_DEBUG_FS
  121. /**
  122. * ti_sci_debug_show() - Helper to dump the debug log
  123. * @s: sequence file pointer
  124. * @unused: unused.
  125. *
  126. * Return: 0
  127. */
  128. static int ti_sci_debug_show(struct seq_file *s, void *unused)
  129. {
  130. struct ti_sci_info *info = s->private;
  131. memcpy_fromio(info->debug_buffer, info->debug_region,
  132. info->debug_region_size);
  133. /*
  134. * We don't trust firmware to leave NULL terminated last byte (hence
  135. * we have allocated 1 extra 0 byte). Since we cannot guarantee any
  136. * specific data format for debug messages, We just present the data
  137. * in the buffer as is - we expect the messages to be self explanatory.
  138. */
  139. seq_puts(s, info->debug_buffer);
  140. return 0;
  141. }
  142. /* Provide the log file operations interface*/
  143. DEFINE_SHOW_ATTRIBUTE(ti_sci_debug);
  144. /**
  145. * ti_sci_debugfs_create() - Create log debug file
  146. * @pdev: platform device pointer
  147. * @info: Pointer to SCI entity information
  148. *
  149. * Return: 0 if all went fine, else corresponding error.
  150. */
  151. static int ti_sci_debugfs_create(struct platform_device *pdev,
  152. struct ti_sci_info *info)
  153. {
  154. struct device *dev = &pdev->dev;
  155. struct resource *res;
  156. char debug_name[50];
  157. /* Debug region is optional */
  158. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  159. "debug_messages");
  160. info->debug_region = devm_ioremap_resource(dev, res);
  161. if (IS_ERR(info->debug_region))
  162. return 0;
  163. info->debug_region_size = resource_size(res);
  164. info->debug_buffer = devm_kcalloc(dev, info->debug_region_size + 1,
  165. sizeof(char), GFP_KERNEL);
  166. if (!info->debug_buffer)
  167. return -ENOMEM;
  168. /* Setup NULL termination */
  169. info->debug_buffer[info->debug_region_size] = 0;
  170. snprintf(debug_name, sizeof(debug_name), "ti_sci_debug@%s",
  171. dev_name(dev));
  172. info->d = debugfs_create_file(debug_name, 0444, NULL, info,
  173. &ti_sci_debug_fops);
  174. if (IS_ERR(info->d))
  175. return PTR_ERR(info->d);
  176. dev_dbg(dev, "Debug region => %p, size = %zu bytes, resource: %pr\n",
  177. info->debug_region, info->debug_region_size, res);
  178. return 0;
  179. }
  180. #else /* CONFIG_DEBUG_FS */
  181. static inline int ti_sci_debugfs_create(struct platform_device *dev,
  182. struct ti_sci_info *info)
  183. {
  184. return 0;
  185. }
  186. static inline void ti_sci_debugfs_destroy(struct platform_device *dev,
  187. struct ti_sci_info *info)
  188. {
  189. }
  190. #endif /* CONFIG_DEBUG_FS */
  191. /**
  192. * ti_sci_dump_header_dbg() - Helper to dump a message header.
  193. * @dev: Device pointer corresponding to the SCI entity
  194. * @hdr: pointer to header.
  195. */
  196. static inline void ti_sci_dump_header_dbg(struct device *dev,
  197. struct ti_sci_msg_hdr *hdr)
  198. {
  199. dev_dbg(dev, "MSGHDR:type=0x%04x host=0x%02x seq=0x%02x flags=0x%08x\n",
  200. hdr->type, hdr->host, hdr->seq, hdr->flags);
  201. }
  202. /**
  203. * ti_sci_rx_callback() - mailbox client callback for receive messages
  204. * @cl: client pointer
  205. * @m: mailbox message
  206. *
  207. * Processes one received message to appropriate transfer information and
  208. * signals completion of the transfer.
  209. *
  210. * NOTE: This function will be invoked in IRQ context, hence should be
  211. * as optimal as possible.
  212. */
  213. static void ti_sci_rx_callback(struct mbox_client *cl, void *m)
  214. {
  215. struct ti_sci_info *info = cl_to_ti_sci_info(cl);
  216. struct device *dev = info->dev;
  217. struct ti_sci_xfers_info *minfo = &info->minfo;
  218. struct ti_msgmgr_message *mbox_msg = m;
  219. struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)mbox_msg->buf;
  220. struct ti_sci_xfer *xfer;
  221. u8 xfer_id;
  222. xfer_id = hdr->seq;
  223. /*
  224. * Are we even expecting this?
  225. * NOTE: barriers were implicit in locks used for modifying the bitmap
  226. */
  227. if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
  228. dev_err(dev, "Message for %d is not expected!\n", xfer_id);
  229. return;
  230. }
  231. xfer = &minfo->xfer_block[xfer_id];
  232. /* Is the message of valid length? */
  233. if (mbox_msg->len > info->desc->max_msg_size) {
  234. dev_err(dev, "Unable to handle %zu xfer(max %d)\n",
  235. mbox_msg->len, info->desc->max_msg_size);
  236. ti_sci_dump_header_dbg(dev, hdr);
  237. return;
  238. }
  239. if (mbox_msg->len < xfer->rx_len) {
  240. dev_err(dev, "Recv xfer %zu < expected %d length\n",
  241. mbox_msg->len, xfer->rx_len);
  242. ti_sci_dump_header_dbg(dev, hdr);
  243. return;
  244. }
  245. ti_sci_dump_header_dbg(dev, hdr);
  246. /* Take a copy to the rx buffer.. */
  247. memcpy(xfer->xfer_buf, mbox_msg->buf, xfer->rx_len);
  248. complete(&xfer->done);
  249. }
  250. /**
  251. * ti_sci_get_one_xfer() - Allocate one message
  252. * @info: Pointer to SCI entity information
  253. * @msg_type: Message type
  254. * @msg_flags: Flag to set for the message
  255. * @tx_message_size: transmit message size
  256. * @rx_message_size: receive message size
  257. *
  258. * Helper function which is used by various command functions that are
  259. * exposed to clients of this driver for allocating a message traffic event.
  260. *
  261. * This function can sleep depending on pending requests already in the system
  262. * for the SCI entity. Further, this also holds a spinlock to maintain integrity
  263. * of internal data structures.
  264. *
  265. * Return: 0 if all went fine, else corresponding error.
  266. */
  267. static struct ti_sci_xfer *ti_sci_get_one_xfer(struct ti_sci_info *info,
  268. u16 msg_type, u32 msg_flags,
  269. size_t tx_message_size,
  270. size_t rx_message_size)
  271. {
  272. struct ti_sci_xfers_info *minfo = &info->minfo;
  273. struct ti_sci_xfer *xfer;
  274. struct ti_sci_msg_hdr *hdr;
  275. unsigned long flags;
  276. unsigned long bit_pos;
  277. u8 xfer_id;
  278. int ret;
  279. int timeout;
  280. /* Ensure we have sane transfer sizes */
  281. if (rx_message_size > info->desc->max_msg_size ||
  282. tx_message_size > info->desc->max_msg_size ||
  283. rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr))
  284. return ERR_PTR(-ERANGE);
  285. /*
  286. * Ensure we have only controlled number of pending messages.
  287. * Ideally, we might just have to wait a single message, be
  288. * conservative and wait 5 times that..
  289. */
  290. timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms) * 5;
  291. ret = down_timeout(&minfo->sem_xfer_count, timeout);
  292. if (ret < 0)
  293. return ERR_PTR(ret);
  294. /* Keep the locked section as small as possible */
  295. spin_lock_irqsave(&minfo->xfer_lock, flags);
  296. bit_pos = find_first_zero_bit(minfo->xfer_alloc_table,
  297. info->desc->max_msgs);
  298. set_bit(bit_pos, minfo->xfer_alloc_table);
  299. spin_unlock_irqrestore(&minfo->xfer_lock, flags);
  300. /*
  301. * We already ensured in probe that we can have max messages that can
  302. * fit in hdr.seq - NOTE: this improves access latencies
  303. * to predictable O(1) access, BUT, it opens us to risk if
  304. * remote misbehaves with corrupted message sequence responses.
  305. * If that happens, we are going to be messed up anyways..
  306. */
  307. xfer_id = (u8)bit_pos;
  308. xfer = &minfo->xfer_block[xfer_id];
  309. hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  310. xfer->tx_message.len = tx_message_size;
  311. xfer->tx_message.chan_rx = info->chan_rx;
  312. xfer->tx_message.timeout_rx_ms = info->desc->max_rx_timeout_ms;
  313. xfer->rx_len = (u8)rx_message_size;
  314. reinit_completion(&xfer->done);
  315. hdr->seq = xfer_id;
  316. hdr->type = msg_type;
  317. hdr->host = info->host_id;
  318. hdr->flags = msg_flags;
  319. return xfer;
  320. }
  321. /**
  322. * ti_sci_put_one_xfer() - Release a message
  323. * @minfo: transfer info pointer
  324. * @xfer: message that was reserved by ti_sci_get_one_xfer
  325. *
  326. * This holds a spinlock to maintain integrity of internal data structures.
  327. */
  328. static void ti_sci_put_one_xfer(struct ti_sci_xfers_info *minfo,
  329. struct ti_sci_xfer *xfer)
  330. {
  331. unsigned long flags;
  332. struct ti_sci_msg_hdr *hdr;
  333. u8 xfer_id;
  334. hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  335. xfer_id = hdr->seq;
  336. /*
  337. * Keep the locked section as small as possible
  338. * NOTE: we might escape with smp_mb and no lock here..
  339. * but just be conservative and symmetric.
  340. */
  341. spin_lock_irqsave(&minfo->xfer_lock, flags);
  342. clear_bit(xfer_id, minfo->xfer_alloc_table);
  343. spin_unlock_irqrestore(&minfo->xfer_lock, flags);
  344. /* Increment the count for the next user to get through */
  345. up(&minfo->sem_xfer_count);
  346. }
  347. /**
  348. * ti_sci_do_xfer() - Do one transfer
  349. * @info: Pointer to SCI entity information
  350. * @xfer: Transfer to initiate and wait for response
  351. *
  352. * Return: -ETIMEDOUT in case of no response, if transmit error,
  353. * return corresponding error, else if all goes well,
  354. * return 0.
  355. */
  356. static inline int ti_sci_do_xfer(struct ti_sci_info *info,
  357. struct ti_sci_xfer *xfer)
  358. {
  359. struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  360. bool response_expected = !!(hdr->flags & (TI_SCI_FLAG_REQ_ACK_ON_PROCESSED |
  361. TI_SCI_FLAG_REQ_ACK_ON_RECEIVED));
  362. int ret;
  363. int timeout;
  364. struct device *dev = info->dev;
  365. bool done_state = true;
  366. ret = mbox_send_message(info->chan_tx, &xfer->tx_message);
  367. if (ret < 0)
  368. return ret;
  369. ret = 0;
  370. if (response_expected && system_state <= SYSTEM_RUNNING) {
  371. /* And we wait for the response. */
  372. timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
  373. if (!wait_for_completion_timeout(&xfer->done, timeout))
  374. ret = -ETIMEDOUT;
  375. } else if (response_expected) {
  376. /*
  377. * If we are !running, we cannot use wait_for_completion_timeout
  378. * during noirq phase, so we must manually poll the completion.
  379. */
  380. ret = read_poll_timeout_atomic(try_wait_for_completion, done_state,
  381. done_state, 1,
  382. info->desc->max_rx_timeout_ms * 1000,
  383. false, &xfer->done);
  384. }
  385. if (ret == -ETIMEDOUT)
  386. dev_err(dev, "Mbox timedout in resp(caller: %pS)\n",
  387. (void *)_RET_IP_);
  388. /*
  389. * NOTE: we might prefer not to need the mailbox ticker to manage the
  390. * transfer queueing since the protocol layer queues things by itself.
  391. * Unfortunately, we have to kick the mailbox framework after we have
  392. * received our message.
  393. */
  394. mbox_client_txdone(info->chan_tx, ret);
  395. return ret;
  396. }
  397. /**
  398. * ti_sci_cmd_get_revision() - command to get the revision of the SCI entity
  399. * @info: Pointer to SCI entity information
  400. *
  401. * Updates the SCI information in the internal data structure.
  402. *
  403. * Return: 0 if all went fine, else return appropriate error.
  404. */
  405. static int ti_sci_cmd_get_revision(struct ti_sci_info *info)
  406. {
  407. struct device *dev = info->dev;
  408. struct ti_sci_handle *handle = &info->handle;
  409. struct ti_sci_version_info *ver = &handle->version;
  410. struct ti_sci_msg_resp_version *rev_info;
  411. struct ti_sci_xfer *xfer;
  412. int ret;
  413. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_VERSION,
  414. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  415. sizeof(struct ti_sci_msg_hdr),
  416. sizeof(*rev_info));
  417. if (IS_ERR(xfer)) {
  418. ret = PTR_ERR(xfer);
  419. dev_err(dev, "Message alloc failed(%d)\n", ret);
  420. return ret;
  421. }
  422. rev_info = (struct ti_sci_msg_resp_version *)xfer->xfer_buf;
  423. ret = ti_sci_do_xfer(info, xfer);
  424. if (ret) {
  425. dev_err(dev, "Mbox send fail %d\n", ret);
  426. goto fail;
  427. }
  428. ver->abi_major = rev_info->abi_major;
  429. ver->abi_minor = rev_info->abi_minor;
  430. ver->firmware_revision = rev_info->firmware_revision;
  431. strscpy(ver->firmware_description, rev_info->firmware_description,
  432. sizeof(ver->firmware_description));
  433. fail:
  434. ti_sci_put_one_xfer(&info->minfo, xfer);
  435. return ret;
  436. }
  437. /**
  438. * ti_sci_is_response_ack() - Generic ACK/NACK message checkup
  439. * @r: pointer to response buffer
  440. *
  441. * Return: true if the response was an ACK, else returns false.
  442. */
  443. static inline bool ti_sci_is_response_ack(void *r)
  444. {
  445. struct ti_sci_msg_hdr *hdr = r;
  446. return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
  447. }
  448. /**
  449. * ti_sci_set_device_state() - Set device state helper
  450. * @handle: pointer to TI SCI handle
  451. * @id: Device identifier
  452. * @flags: flags to setup for the device
  453. * @state: State to move the device to
  454. *
  455. * Return: 0 if all went well, else returns appropriate error value.
  456. */
  457. static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
  458. u32 id, u32 flags, u8 state)
  459. {
  460. struct ti_sci_info *info;
  461. struct ti_sci_msg_req_set_device_state *req;
  462. struct ti_sci_msg_hdr *resp;
  463. struct ti_sci_xfer *xfer;
  464. struct device *dev;
  465. int ret = 0;
  466. if (IS_ERR(handle))
  467. return PTR_ERR(handle);
  468. if (!handle)
  469. return -EINVAL;
  470. info = handle_to_ti_sci_info(handle);
  471. dev = info->dev;
  472. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
  473. flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  474. sizeof(*req), sizeof(*resp));
  475. if (IS_ERR(xfer)) {
  476. ret = PTR_ERR(xfer);
  477. dev_err(dev, "Message alloc failed(%d)\n", ret);
  478. return ret;
  479. }
  480. req = (struct ti_sci_msg_req_set_device_state *)xfer->xfer_buf;
  481. req->id = id;
  482. req->state = state;
  483. ret = ti_sci_do_xfer(info, xfer);
  484. if (ret) {
  485. dev_err(dev, "Mbox send fail %d\n", ret);
  486. goto fail;
  487. }
  488. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  489. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  490. fail:
  491. ti_sci_put_one_xfer(&info->minfo, xfer);
  492. return ret;
  493. }
  494. /**
  495. * ti_sci_get_device_state() - Get device state helper
  496. * @handle: Handle to the device
  497. * @id: Device Identifier
  498. * @clcnt: Pointer to Context Loss Count
  499. * @resets: pointer to resets
  500. * @p_state: pointer to p_state
  501. * @c_state: pointer to c_state
  502. *
  503. * Return: 0 if all went fine, else return appropriate error.
  504. */
  505. static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
  506. u32 id, u32 *clcnt, u32 *resets,
  507. u8 *p_state, u8 *c_state)
  508. {
  509. struct ti_sci_info *info;
  510. struct ti_sci_msg_req_get_device_state *req;
  511. struct ti_sci_msg_resp_get_device_state *resp;
  512. struct ti_sci_xfer *xfer;
  513. struct device *dev;
  514. int ret = 0;
  515. if (IS_ERR(handle))
  516. return PTR_ERR(handle);
  517. if (!handle)
  518. return -EINVAL;
  519. if (!clcnt && !resets && !p_state && !c_state)
  520. return -EINVAL;
  521. info = handle_to_ti_sci_info(handle);
  522. dev = info->dev;
  523. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE,
  524. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  525. sizeof(*req), sizeof(*resp));
  526. if (IS_ERR(xfer)) {
  527. ret = PTR_ERR(xfer);
  528. dev_err(dev, "Message alloc failed(%d)\n", ret);
  529. return ret;
  530. }
  531. req = (struct ti_sci_msg_req_get_device_state *)xfer->xfer_buf;
  532. req->id = id;
  533. ret = ti_sci_do_xfer(info, xfer);
  534. if (ret) {
  535. dev_err(dev, "Mbox send fail %d\n", ret);
  536. goto fail;
  537. }
  538. resp = (struct ti_sci_msg_resp_get_device_state *)xfer->xfer_buf;
  539. if (!ti_sci_is_response_ack(resp)) {
  540. ret = -ENODEV;
  541. goto fail;
  542. }
  543. if (clcnt)
  544. *clcnt = resp->context_loss_count;
  545. if (resets)
  546. *resets = resp->resets;
  547. if (p_state)
  548. *p_state = resp->programmed_state;
  549. if (c_state)
  550. *c_state = resp->current_state;
  551. fail:
  552. ti_sci_put_one_xfer(&info->minfo, xfer);
  553. return ret;
  554. }
  555. /**
  556. * ti_sci_cmd_get_device() - command to request for device managed by TISCI
  557. * that can be shared with other hosts.
  558. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  559. * @id: Device Identifier
  560. *
  561. * Request for the device - NOTE: the client MUST maintain integrity of
  562. * usage count by balancing get_device with put_device. No refcounting is
  563. * managed by driver for that purpose.
  564. *
  565. * Return: 0 if all went fine, else return appropriate error.
  566. */
  567. static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id)
  568. {
  569. return ti_sci_set_device_state(handle, id, 0,
  570. MSG_DEVICE_SW_STATE_ON);
  571. }
  572. /**
  573. * ti_sci_cmd_get_device_exclusive() - command to request for device managed by
  574. * TISCI that is exclusively owned by the
  575. * requesting host.
  576. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  577. * @id: Device Identifier
  578. *
  579. * Request for the device - NOTE: the client MUST maintain integrity of
  580. * usage count by balancing get_device with put_device. No refcounting is
  581. * managed by driver for that purpose.
  582. *
  583. * Return: 0 if all went fine, else return appropriate error.
  584. */
  585. static int ti_sci_cmd_get_device_exclusive(const struct ti_sci_handle *handle,
  586. u32 id)
  587. {
  588. return ti_sci_set_device_state(handle, id,
  589. MSG_FLAG_DEVICE_EXCLUSIVE,
  590. MSG_DEVICE_SW_STATE_ON);
  591. }
  592. /**
  593. * ti_sci_cmd_idle_device() - Command to idle a device managed by TISCI
  594. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  595. * @id: Device Identifier
  596. *
  597. * Request for the device - NOTE: the client MUST maintain integrity of
  598. * usage count by balancing get_device with put_device. No refcounting is
  599. * managed by driver for that purpose.
  600. *
  601. * Return: 0 if all went fine, else return appropriate error.
  602. */
  603. static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id)
  604. {
  605. return ti_sci_set_device_state(handle, id, 0,
  606. MSG_DEVICE_SW_STATE_RETENTION);
  607. }
  608. /**
  609. * ti_sci_cmd_idle_device_exclusive() - Command to idle a device managed by
  610. * TISCI that is exclusively owned by
  611. * requesting host.
  612. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  613. * @id: Device Identifier
  614. *
  615. * Request for the device - NOTE: the client MUST maintain integrity of
  616. * usage count by balancing get_device with put_device. No refcounting is
  617. * managed by driver for that purpose.
  618. *
  619. * Return: 0 if all went fine, else return appropriate error.
  620. */
  621. static int ti_sci_cmd_idle_device_exclusive(const struct ti_sci_handle *handle,
  622. u32 id)
  623. {
  624. return ti_sci_set_device_state(handle, id,
  625. MSG_FLAG_DEVICE_EXCLUSIVE,
  626. MSG_DEVICE_SW_STATE_RETENTION);
  627. }
  628. /**
  629. * ti_sci_cmd_put_device() - command to release a device managed by TISCI
  630. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  631. * @id: Device Identifier
  632. *
  633. * Request for the device - NOTE: the client MUST maintain integrity of
  634. * usage count by balancing get_device with put_device. No refcounting is
  635. * managed by driver for that purpose.
  636. *
  637. * Return: 0 if all went fine, else return appropriate error.
  638. */
  639. static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id)
  640. {
  641. return ti_sci_set_device_state(handle, id,
  642. 0, MSG_DEVICE_SW_STATE_AUTO_OFF);
  643. }
  644. /**
  645. * ti_sci_cmd_dev_is_valid() - Is the device valid
  646. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  647. * @id: Device Identifier
  648. *
  649. * Return: 0 if all went fine and the device ID is valid, else return
  650. * appropriate error.
  651. */
  652. static int ti_sci_cmd_dev_is_valid(const struct ti_sci_handle *handle, u32 id)
  653. {
  654. u8 unused;
  655. /* check the device state which will also tell us if the ID is valid */
  656. return ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &unused);
  657. }
  658. /**
  659. * ti_sci_cmd_dev_get_clcnt() - Get context loss counter
  660. * @handle: Pointer to TISCI handle
  661. * @id: Device Identifier
  662. * @count: Pointer to Context Loss counter to populate
  663. *
  664. * Return: 0 if all went fine, else return appropriate error.
  665. */
  666. static int ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle *handle, u32 id,
  667. u32 *count)
  668. {
  669. return ti_sci_get_device_state(handle, id, count, NULL, NULL, NULL);
  670. }
  671. /**
  672. * ti_sci_cmd_dev_is_idle() - Check if the device is requested to be idle
  673. * @handle: Pointer to TISCI handle
  674. * @id: Device Identifier
  675. * @r_state: true if requested to be idle
  676. *
  677. * Return: 0 if all went fine, else return appropriate error.
  678. */
  679. static int ti_sci_cmd_dev_is_idle(const struct ti_sci_handle *handle, u32 id,
  680. bool *r_state)
  681. {
  682. int ret;
  683. u8 state;
  684. if (!r_state)
  685. return -EINVAL;
  686. ret = ti_sci_get_device_state(handle, id, NULL, NULL, &state, NULL);
  687. if (ret)
  688. return ret;
  689. *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION);
  690. return 0;
  691. }
  692. /**
  693. * ti_sci_cmd_dev_is_stop() - Check if the device is requested to be stopped
  694. * @handle: Pointer to TISCI handle
  695. * @id: Device Identifier
  696. * @r_state: true if requested to be stopped
  697. * @curr_state: true if currently stopped.
  698. *
  699. * Return: 0 if all went fine, else return appropriate error.
  700. */
  701. static int ti_sci_cmd_dev_is_stop(const struct ti_sci_handle *handle, u32 id,
  702. bool *r_state, bool *curr_state)
  703. {
  704. int ret;
  705. u8 p_state, c_state;
  706. if (!r_state && !curr_state)
  707. return -EINVAL;
  708. ret =
  709. ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
  710. if (ret)
  711. return ret;
  712. if (r_state)
  713. *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF);
  714. if (curr_state)
  715. *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF);
  716. return 0;
  717. }
  718. /**
  719. * ti_sci_cmd_dev_is_on() - Check if the device is requested to be ON
  720. * @handle: Pointer to TISCI handle
  721. * @id: Device Identifier
  722. * @r_state: true if requested to be ON
  723. * @curr_state: true if currently ON and active
  724. *
  725. * Return: 0 if all went fine, else return appropriate error.
  726. */
  727. static int ti_sci_cmd_dev_is_on(const struct ti_sci_handle *handle, u32 id,
  728. bool *r_state, bool *curr_state)
  729. {
  730. int ret;
  731. u8 p_state, c_state;
  732. if (!r_state && !curr_state)
  733. return -EINVAL;
  734. ret =
  735. ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
  736. if (ret)
  737. return ret;
  738. if (r_state)
  739. *r_state = (p_state == MSG_DEVICE_SW_STATE_ON);
  740. if (curr_state)
  741. *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON);
  742. return 0;
  743. }
  744. /**
  745. * ti_sci_cmd_dev_is_trans() - Check if the device is currently transitioning
  746. * @handle: Pointer to TISCI handle
  747. * @id: Device Identifier
  748. * @curr_state: true if currently transitioning.
  749. *
  750. * Return: 0 if all went fine, else return appropriate error.
  751. */
  752. static int ti_sci_cmd_dev_is_trans(const struct ti_sci_handle *handle, u32 id,
  753. bool *curr_state)
  754. {
  755. int ret;
  756. u8 state;
  757. if (!curr_state)
  758. return -EINVAL;
  759. ret = ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &state);
  760. if (ret)
  761. return ret;
  762. *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS);
  763. return 0;
  764. }
  765. /**
  766. * ti_sci_cmd_set_device_resets() - command to set resets for device managed
  767. * by TISCI
  768. * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  769. * @id: Device Identifier
  770. * @reset_state: Device specific reset bit field
  771. *
  772. * Return: 0 if all went fine, else return appropriate error.
  773. */
  774. static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle,
  775. u32 id, u32 reset_state)
  776. {
  777. struct ti_sci_info *info;
  778. struct ti_sci_msg_req_set_device_resets *req;
  779. struct ti_sci_msg_hdr *resp;
  780. struct ti_sci_xfer *xfer;
  781. struct device *dev;
  782. int ret = 0;
  783. if (IS_ERR(handle))
  784. return PTR_ERR(handle);
  785. if (!handle)
  786. return -EINVAL;
  787. info = handle_to_ti_sci_info(handle);
  788. dev = info->dev;
  789. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_RESETS,
  790. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  791. sizeof(*req), sizeof(*resp));
  792. if (IS_ERR(xfer)) {
  793. ret = PTR_ERR(xfer);
  794. dev_err(dev, "Message alloc failed(%d)\n", ret);
  795. return ret;
  796. }
  797. req = (struct ti_sci_msg_req_set_device_resets *)xfer->xfer_buf;
  798. req->id = id;
  799. req->resets = reset_state;
  800. ret = ti_sci_do_xfer(info, xfer);
  801. if (ret) {
  802. dev_err(dev, "Mbox send fail %d\n", ret);
  803. goto fail;
  804. }
  805. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  806. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  807. fail:
  808. ti_sci_put_one_xfer(&info->minfo, xfer);
  809. return ret;
  810. }
  811. /**
  812. * ti_sci_cmd_get_device_resets() - Get reset state for device managed
  813. * by TISCI
  814. * @handle: Pointer to TISCI handle
  815. * @id: Device Identifier
  816. * @reset_state: Pointer to reset state to populate
  817. *
  818. * Return: 0 if all went fine, else return appropriate error.
  819. */
  820. static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle,
  821. u32 id, u32 *reset_state)
  822. {
  823. return ti_sci_get_device_state(handle, id, NULL, reset_state, NULL,
  824. NULL);
  825. }
  826. /**
  827. * ti_sci_set_clock_state() - Set clock state helper
  828. * @handle: pointer to TI SCI handle
  829. * @dev_id: Device identifier this request is for
  830. * @clk_id: Clock identifier for the device for this request.
  831. * Each device has it's own set of clock inputs. This indexes
  832. * which clock input to modify.
  833. * @flags: Header flags as needed
  834. * @state: State to request for the clock.
  835. *
  836. * Return: 0 if all went well, else returns appropriate error value.
  837. */
  838. static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
  839. u32 dev_id, u32 clk_id,
  840. u32 flags, u8 state)
  841. {
  842. struct ti_sci_info *info;
  843. struct ti_sci_msg_req_set_clock_state *req;
  844. struct ti_sci_msg_hdr *resp;
  845. struct ti_sci_xfer *xfer;
  846. struct device *dev;
  847. int ret = 0;
  848. if (IS_ERR(handle))
  849. return PTR_ERR(handle);
  850. if (!handle)
  851. return -EINVAL;
  852. info = handle_to_ti_sci_info(handle);
  853. dev = info->dev;
  854. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_STATE,
  855. flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  856. sizeof(*req), sizeof(*resp));
  857. if (IS_ERR(xfer)) {
  858. ret = PTR_ERR(xfer);
  859. dev_err(dev, "Message alloc failed(%d)\n", ret);
  860. return ret;
  861. }
  862. req = (struct ti_sci_msg_req_set_clock_state *)xfer->xfer_buf;
  863. req->dev_id = dev_id;
  864. if (clk_id < 255) {
  865. req->clk_id = clk_id;
  866. } else {
  867. req->clk_id = 255;
  868. req->clk_id_32 = clk_id;
  869. }
  870. req->request_state = state;
  871. ret = ti_sci_do_xfer(info, xfer);
  872. if (ret) {
  873. dev_err(dev, "Mbox send fail %d\n", ret);
  874. goto fail;
  875. }
  876. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  877. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  878. fail:
  879. ti_sci_put_one_xfer(&info->minfo, xfer);
  880. return ret;
  881. }
  882. /**
  883. * ti_sci_cmd_get_clock_state() - Get clock state helper
  884. * @handle: pointer to TI SCI handle
  885. * @dev_id: Device identifier this request is for
  886. * @clk_id: Clock identifier for the device for this request.
  887. * Each device has it's own set of clock inputs. This indexes
  888. * which clock input to modify.
  889. * @programmed_state: State requested for clock to move to
  890. * @current_state: State that the clock is currently in
  891. *
  892. * Return: 0 if all went well, else returns appropriate error value.
  893. */
  894. static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle,
  895. u32 dev_id, u32 clk_id,
  896. u8 *programmed_state, u8 *current_state)
  897. {
  898. struct ti_sci_info *info;
  899. struct ti_sci_msg_req_get_clock_state *req;
  900. struct ti_sci_msg_resp_get_clock_state *resp;
  901. struct ti_sci_xfer *xfer;
  902. struct device *dev;
  903. int ret = 0;
  904. if (IS_ERR(handle))
  905. return PTR_ERR(handle);
  906. if (!handle)
  907. return -EINVAL;
  908. if (!programmed_state && !current_state)
  909. return -EINVAL;
  910. info = handle_to_ti_sci_info(handle);
  911. dev = info->dev;
  912. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_STATE,
  913. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  914. sizeof(*req), sizeof(*resp));
  915. if (IS_ERR(xfer)) {
  916. ret = PTR_ERR(xfer);
  917. dev_err(dev, "Message alloc failed(%d)\n", ret);
  918. return ret;
  919. }
  920. req = (struct ti_sci_msg_req_get_clock_state *)xfer->xfer_buf;
  921. req->dev_id = dev_id;
  922. if (clk_id < 255) {
  923. req->clk_id = clk_id;
  924. } else {
  925. req->clk_id = 255;
  926. req->clk_id_32 = clk_id;
  927. }
  928. ret = ti_sci_do_xfer(info, xfer);
  929. if (ret) {
  930. dev_err(dev, "Mbox send fail %d\n", ret);
  931. goto fail;
  932. }
  933. resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->xfer_buf;
  934. if (!ti_sci_is_response_ack(resp)) {
  935. ret = -ENODEV;
  936. goto fail;
  937. }
  938. if (programmed_state)
  939. *programmed_state = resp->programmed_state;
  940. if (current_state)
  941. *current_state = resp->current_state;
  942. fail:
  943. ti_sci_put_one_xfer(&info->minfo, xfer);
  944. return ret;
  945. }
  946. /**
  947. * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI
  948. * @handle: pointer to TI SCI handle
  949. * @dev_id: Device identifier this request is for
  950. * @clk_id: Clock identifier for the device for this request.
  951. * Each device has it's own set of clock inputs. This indexes
  952. * which clock input to modify.
  953. * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false'
  954. * @can_change_freq: 'true' if frequency change is desired, else 'false'
  955. * @enable_input_term: 'true' if input termination is desired, else 'false'
  956. *
  957. * Return: 0 if all went well, else returns appropriate error value.
  958. */
  959. static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id,
  960. u32 clk_id, bool needs_ssc,
  961. bool can_change_freq, bool enable_input_term)
  962. {
  963. u32 flags = 0;
  964. flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0;
  965. flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0;
  966. flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0;
  967. return ti_sci_set_clock_state(handle, dev_id, clk_id, flags,
  968. MSG_CLOCK_SW_STATE_REQ);
  969. }
  970. /**
  971. * ti_sci_cmd_idle_clock() - Idle a clock which is in our control
  972. * @handle: pointer to TI SCI handle
  973. * @dev_id: Device identifier this request is for
  974. * @clk_id: Clock identifier for the device for this request.
  975. * Each device has it's own set of clock inputs. This indexes
  976. * which clock input to modify.
  977. *
  978. * NOTE: This clock must have been requested by get_clock previously.
  979. *
  980. * Return: 0 if all went well, else returns appropriate error value.
  981. */
  982. static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle,
  983. u32 dev_id, u32 clk_id)
  984. {
  985. return ti_sci_set_clock_state(handle, dev_id, clk_id,
  986. MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
  987. MSG_CLOCK_SW_STATE_UNREQ);
  988. }
  989. /**
  990. * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI
  991. * @handle: pointer to TI SCI handle
  992. * @dev_id: Device identifier this request is for
  993. * @clk_id: Clock identifier for the device for this request.
  994. * Each device has it's own set of clock inputs. This indexes
  995. * which clock input to modify.
  996. *
  997. * NOTE: This clock must have been requested by get_clock previously.
  998. *
  999. * Return: 0 if all went well, else returns appropriate error value.
  1000. */
  1001. static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle,
  1002. u32 dev_id, u32 clk_id)
  1003. {
  1004. return ti_sci_set_clock_state(handle, dev_id, clk_id,
  1005. MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
  1006. MSG_CLOCK_SW_STATE_AUTO);
  1007. }
  1008. /**
  1009. * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed
  1010. * @handle: pointer to TI SCI handle
  1011. * @dev_id: Device identifier this request is for
  1012. * @clk_id: Clock identifier for the device for this request.
  1013. * Each device has it's own set of clock inputs. This indexes
  1014. * which clock input to modify.
  1015. * @req_state: state indicating if the clock is auto managed
  1016. *
  1017. * Return: 0 if all went well, else returns appropriate error value.
  1018. */
  1019. static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle,
  1020. u32 dev_id, u32 clk_id, bool *req_state)
  1021. {
  1022. u8 state = 0;
  1023. int ret;
  1024. if (!req_state)
  1025. return -EINVAL;
  1026. ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL);
  1027. if (ret)
  1028. return ret;
  1029. *req_state = (state == MSG_CLOCK_SW_STATE_AUTO);
  1030. return 0;
  1031. }
  1032. /**
  1033. * ti_sci_cmd_clk_is_on() - Is the clock ON
  1034. * @handle: pointer to TI SCI handle
  1035. * @dev_id: Device identifier this request is for
  1036. * @clk_id: Clock identifier for the device for this request.
  1037. * Each device has it's own set of clock inputs. This indexes
  1038. * which clock input to modify.
  1039. * @req_state: state indicating if the clock is managed by us and enabled
  1040. * @curr_state: state indicating if the clock is ready for operation
  1041. *
  1042. * Return: 0 if all went well, else returns appropriate error value.
  1043. */
  1044. static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id,
  1045. u32 clk_id, bool *req_state, bool *curr_state)
  1046. {
  1047. u8 c_state = 0, r_state = 0;
  1048. int ret;
  1049. if (!req_state && !curr_state)
  1050. return -EINVAL;
  1051. ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
  1052. &r_state, &c_state);
  1053. if (ret)
  1054. return ret;
  1055. if (req_state)
  1056. *req_state = (r_state == MSG_CLOCK_SW_STATE_REQ);
  1057. if (curr_state)
  1058. *curr_state = (c_state == MSG_CLOCK_HW_STATE_READY);
  1059. return 0;
  1060. }
  1061. /**
  1062. * ti_sci_cmd_clk_is_off() - Is the clock OFF
  1063. * @handle: pointer to TI SCI handle
  1064. * @dev_id: Device identifier this request is for
  1065. * @clk_id: Clock identifier for the device for this request.
  1066. * Each device has it's own set of clock inputs. This indexes
  1067. * which clock input to modify.
  1068. * @req_state: state indicating if the clock is managed by us and disabled
  1069. * @curr_state: state indicating if the clock is NOT ready for operation
  1070. *
  1071. * Return: 0 if all went well, else returns appropriate error value.
  1072. */
  1073. static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id,
  1074. u32 clk_id, bool *req_state, bool *curr_state)
  1075. {
  1076. u8 c_state = 0, r_state = 0;
  1077. int ret;
  1078. if (!req_state && !curr_state)
  1079. return -EINVAL;
  1080. ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
  1081. &r_state, &c_state);
  1082. if (ret)
  1083. return ret;
  1084. if (req_state)
  1085. *req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ);
  1086. if (curr_state)
  1087. *curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY);
  1088. return 0;
  1089. }
  1090. /**
  1091. * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock
  1092. * @handle: pointer to TI SCI handle
  1093. * @dev_id: Device identifier this request is for
  1094. * @clk_id: Clock identifier for the device for this request.
  1095. * Each device has it's own set of clock inputs. This indexes
  1096. * which clock input to modify.
  1097. * @parent_id: Parent clock identifier to set
  1098. *
  1099. * Return: 0 if all went well, else returns appropriate error value.
  1100. */
  1101. static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
  1102. u32 dev_id, u32 clk_id, u32 parent_id)
  1103. {
  1104. struct ti_sci_info *info;
  1105. struct ti_sci_msg_req_set_clock_parent *req;
  1106. struct ti_sci_msg_hdr *resp;
  1107. struct ti_sci_xfer *xfer;
  1108. struct device *dev;
  1109. int ret = 0;
  1110. if (IS_ERR(handle))
  1111. return PTR_ERR(handle);
  1112. if (!handle)
  1113. return -EINVAL;
  1114. info = handle_to_ti_sci_info(handle);
  1115. dev = info->dev;
  1116. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_PARENT,
  1117. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1118. sizeof(*req), sizeof(*resp));
  1119. if (IS_ERR(xfer)) {
  1120. ret = PTR_ERR(xfer);
  1121. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1122. return ret;
  1123. }
  1124. req = (struct ti_sci_msg_req_set_clock_parent *)xfer->xfer_buf;
  1125. req->dev_id = dev_id;
  1126. if (clk_id < 255) {
  1127. req->clk_id = clk_id;
  1128. } else {
  1129. req->clk_id = 255;
  1130. req->clk_id_32 = clk_id;
  1131. }
  1132. if (parent_id < 255) {
  1133. req->parent_id = parent_id;
  1134. } else {
  1135. req->parent_id = 255;
  1136. req->parent_id_32 = parent_id;
  1137. }
  1138. ret = ti_sci_do_xfer(info, xfer);
  1139. if (ret) {
  1140. dev_err(dev, "Mbox send fail %d\n", ret);
  1141. goto fail;
  1142. }
  1143. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  1144. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  1145. fail:
  1146. ti_sci_put_one_xfer(&info->minfo, xfer);
  1147. return ret;
  1148. }
  1149. /**
  1150. * ti_sci_cmd_clk_get_parent() - Get current parent clock source
  1151. * @handle: pointer to TI SCI handle
  1152. * @dev_id: Device identifier this request is for
  1153. * @clk_id: Clock identifier for the device for this request.
  1154. * Each device has it's own set of clock inputs. This indexes
  1155. * which clock input to modify.
  1156. * @parent_id: Current clock parent
  1157. *
  1158. * Return: 0 if all went well, else returns appropriate error value.
  1159. */
  1160. static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle,
  1161. u32 dev_id, u32 clk_id, u32 *parent_id)
  1162. {
  1163. struct ti_sci_info *info;
  1164. struct ti_sci_msg_req_get_clock_parent *req;
  1165. struct ti_sci_msg_resp_get_clock_parent *resp;
  1166. struct ti_sci_xfer *xfer;
  1167. struct device *dev;
  1168. int ret = 0;
  1169. if (IS_ERR(handle))
  1170. return PTR_ERR(handle);
  1171. if (!handle || !parent_id)
  1172. return -EINVAL;
  1173. info = handle_to_ti_sci_info(handle);
  1174. dev = info->dev;
  1175. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_PARENT,
  1176. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1177. sizeof(*req), sizeof(*resp));
  1178. if (IS_ERR(xfer)) {
  1179. ret = PTR_ERR(xfer);
  1180. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1181. return ret;
  1182. }
  1183. req = (struct ti_sci_msg_req_get_clock_parent *)xfer->xfer_buf;
  1184. req->dev_id = dev_id;
  1185. if (clk_id < 255) {
  1186. req->clk_id = clk_id;
  1187. } else {
  1188. req->clk_id = 255;
  1189. req->clk_id_32 = clk_id;
  1190. }
  1191. ret = ti_sci_do_xfer(info, xfer);
  1192. if (ret) {
  1193. dev_err(dev, "Mbox send fail %d\n", ret);
  1194. goto fail;
  1195. }
  1196. resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->xfer_buf;
  1197. if (!ti_sci_is_response_ack(resp)) {
  1198. ret = -ENODEV;
  1199. } else {
  1200. if (resp->parent_id < 255)
  1201. *parent_id = resp->parent_id;
  1202. else
  1203. *parent_id = resp->parent_id_32;
  1204. }
  1205. fail:
  1206. ti_sci_put_one_xfer(&info->minfo, xfer);
  1207. return ret;
  1208. }
  1209. /**
  1210. * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source
  1211. * @handle: pointer to TI SCI handle
  1212. * @dev_id: Device identifier this request is for
  1213. * @clk_id: Clock identifier for the device for this request.
  1214. * Each device has it's own set of clock inputs. This indexes
  1215. * which clock input to modify.
  1216. * @num_parents: Returns he number of parents to the current clock.
  1217. *
  1218. * Return: 0 if all went well, else returns appropriate error value.
  1219. */
  1220. static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle,
  1221. u32 dev_id, u32 clk_id,
  1222. u32 *num_parents)
  1223. {
  1224. struct ti_sci_info *info;
  1225. struct ti_sci_msg_req_get_clock_num_parents *req;
  1226. struct ti_sci_msg_resp_get_clock_num_parents *resp;
  1227. struct ti_sci_xfer *xfer;
  1228. struct device *dev;
  1229. int ret = 0;
  1230. if (IS_ERR(handle))
  1231. return PTR_ERR(handle);
  1232. if (!handle || !num_parents)
  1233. return -EINVAL;
  1234. info = handle_to_ti_sci_info(handle);
  1235. dev = info->dev;
  1236. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS,
  1237. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1238. sizeof(*req), sizeof(*resp));
  1239. if (IS_ERR(xfer)) {
  1240. ret = PTR_ERR(xfer);
  1241. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1242. return ret;
  1243. }
  1244. req = (struct ti_sci_msg_req_get_clock_num_parents *)xfer->xfer_buf;
  1245. req->dev_id = dev_id;
  1246. if (clk_id < 255) {
  1247. req->clk_id = clk_id;
  1248. } else {
  1249. req->clk_id = 255;
  1250. req->clk_id_32 = clk_id;
  1251. }
  1252. ret = ti_sci_do_xfer(info, xfer);
  1253. if (ret) {
  1254. dev_err(dev, "Mbox send fail %d\n", ret);
  1255. goto fail;
  1256. }
  1257. resp = (struct ti_sci_msg_resp_get_clock_num_parents *)xfer->xfer_buf;
  1258. if (!ti_sci_is_response_ack(resp)) {
  1259. ret = -ENODEV;
  1260. } else {
  1261. if (resp->num_parents < 255)
  1262. *num_parents = resp->num_parents;
  1263. else
  1264. *num_parents = resp->num_parents_32;
  1265. }
  1266. fail:
  1267. ti_sci_put_one_xfer(&info->minfo, xfer);
  1268. return ret;
  1269. }
  1270. /**
  1271. * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency
  1272. * @handle: pointer to TI SCI handle
  1273. * @dev_id: Device identifier this request is for
  1274. * @clk_id: Clock identifier for the device for this request.
  1275. * Each device has it's own set of clock inputs. This indexes
  1276. * which clock input to modify.
  1277. * @min_freq: The minimum allowable frequency in Hz. This is the minimum
  1278. * allowable programmed frequency and does not account for clock
  1279. * tolerances and jitter.
  1280. * @target_freq: The target clock frequency in Hz. A frequency will be
  1281. * processed as close to this target frequency as possible.
  1282. * @max_freq: The maximum allowable frequency in Hz. This is the maximum
  1283. * allowable programmed frequency and does not account for clock
  1284. * tolerances and jitter.
  1285. * @match_freq: Frequency match in Hz response.
  1286. *
  1287. * Return: 0 if all went well, else returns appropriate error value.
  1288. */
  1289. static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
  1290. u32 dev_id, u32 clk_id, u64 min_freq,
  1291. u64 target_freq, u64 max_freq,
  1292. u64 *match_freq)
  1293. {
  1294. struct ti_sci_info *info;
  1295. struct ti_sci_msg_req_query_clock_freq *req;
  1296. struct ti_sci_msg_resp_query_clock_freq *resp;
  1297. struct ti_sci_xfer *xfer;
  1298. struct device *dev;
  1299. int ret = 0;
  1300. if (IS_ERR(handle))
  1301. return PTR_ERR(handle);
  1302. if (!handle || !match_freq)
  1303. return -EINVAL;
  1304. info = handle_to_ti_sci_info(handle);
  1305. dev = info->dev;
  1306. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_QUERY_CLOCK_FREQ,
  1307. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1308. sizeof(*req), sizeof(*resp));
  1309. if (IS_ERR(xfer)) {
  1310. ret = PTR_ERR(xfer);
  1311. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1312. return ret;
  1313. }
  1314. req = (struct ti_sci_msg_req_query_clock_freq *)xfer->xfer_buf;
  1315. req->dev_id = dev_id;
  1316. if (clk_id < 255) {
  1317. req->clk_id = clk_id;
  1318. } else {
  1319. req->clk_id = 255;
  1320. req->clk_id_32 = clk_id;
  1321. }
  1322. req->min_freq_hz = min_freq;
  1323. req->target_freq_hz = target_freq;
  1324. req->max_freq_hz = max_freq;
  1325. ret = ti_sci_do_xfer(info, xfer);
  1326. if (ret) {
  1327. dev_err(dev, "Mbox send fail %d\n", ret);
  1328. goto fail;
  1329. }
  1330. resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->xfer_buf;
  1331. if (!ti_sci_is_response_ack(resp))
  1332. ret = -ENODEV;
  1333. else
  1334. *match_freq = resp->freq_hz;
  1335. fail:
  1336. ti_sci_put_one_xfer(&info->minfo, xfer);
  1337. return ret;
  1338. }
  1339. /**
  1340. * ti_sci_cmd_clk_set_freq() - Set a frequency for clock
  1341. * @handle: pointer to TI SCI handle
  1342. * @dev_id: Device identifier this request is for
  1343. * @clk_id: Clock identifier for the device for this request.
  1344. * Each device has it's own set of clock inputs. This indexes
  1345. * which clock input to modify.
  1346. * @min_freq: The minimum allowable frequency in Hz. This is the minimum
  1347. * allowable programmed frequency and does not account for clock
  1348. * tolerances and jitter.
  1349. * @target_freq: The target clock frequency in Hz. A frequency will be
  1350. * processed as close to this target frequency as possible.
  1351. * @max_freq: The maximum allowable frequency in Hz. This is the maximum
  1352. * allowable programmed frequency and does not account for clock
  1353. * tolerances and jitter.
  1354. *
  1355. * Return: 0 if all went well, else returns appropriate error value.
  1356. */
  1357. static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
  1358. u32 dev_id, u32 clk_id, u64 min_freq,
  1359. u64 target_freq, u64 max_freq)
  1360. {
  1361. struct ti_sci_info *info;
  1362. struct ti_sci_msg_req_set_clock_freq *req;
  1363. struct ti_sci_msg_hdr *resp;
  1364. struct ti_sci_xfer *xfer;
  1365. struct device *dev;
  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. dev = info->dev;
  1373. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_FREQ,
  1374. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1375. sizeof(*req), sizeof(*resp));
  1376. if (IS_ERR(xfer)) {
  1377. ret = PTR_ERR(xfer);
  1378. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1379. return ret;
  1380. }
  1381. req = (struct ti_sci_msg_req_set_clock_freq *)xfer->xfer_buf;
  1382. req->dev_id = dev_id;
  1383. if (clk_id < 255) {
  1384. req->clk_id = clk_id;
  1385. } else {
  1386. req->clk_id = 255;
  1387. req->clk_id_32 = clk_id;
  1388. }
  1389. req->min_freq_hz = min_freq;
  1390. req->target_freq_hz = target_freq;
  1391. req->max_freq_hz = max_freq;
  1392. ret = ti_sci_do_xfer(info, xfer);
  1393. if (ret) {
  1394. dev_err(dev, "Mbox send fail %d\n", ret);
  1395. goto fail;
  1396. }
  1397. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  1398. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  1399. fail:
  1400. ti_sci_put_one_xfer(&info->minfo, xfer);
  1401. return ret;
  1402. }
  1403. /**
  1404. * ti_sci_cmd_clk_get_freq() - Get current frequency
  1405. * @handle: pointer to TI SCI handle
  1406. * @dev_id: Device identifier this request is for
  1407. * @clk_id: Clock identifier for the device for this request.
  1408. * Each device has it's own set of clock inputs. This indexes
  1409. * which clock input to modify.
  1410. * @freq: Currently frequency in Hz
  1411. *
  1412. * Return: 0 if all went well, else returns appropriate error value.
  1413. */
  1414. static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
  1415. u32 dev_id, u32 clk_id, u64 *freq)
  1416. {
  1417. struct ti_sci_info *info;
  1418. struct ti_sci_msg_req_get_clock_freq *req;
  1419. struct ti_sci_msg_resp_get_clock_freq *resp;
  1420. struct ti_sci_xfer *xfer;
  1421. struct device *dev;
  1422. int ret = 0;
  1423. if (IS_ERR(handle))
  1424. return PTR_ERR(handle);
  1425. if (!handle || !freq)
  1426. return -EINVAL;
  1427. info = handle_to_ti_sci_info(handle);
  1428. dev = info->dev;
  1429. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_FREQ,
  1430. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1431. sizeof(*req), sizeof(*resp));
  1432. if (IS_ERR(xfer)) {
  1433. ret = PTR_ERR(xfer);
  1434. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1435. return ret;
  1436. }
  1437. req = (struct ti_sci_msg_req_get_clock_freq *)xfer->xfer_buf;
  1438. req->dev_id = dev_id;
  1439. if (clk_id < 255) {
  1440. req->clk_id = clk_id;
  1441. } else {
  1442. req->clk_id = 255;
  1443. req->clk_id_32 = clk_id;
  1444. }
  1445. ret = ti_sci_do_xfer(info, xfer);
  1446. if (ret) {
  1447. dev_err(dev, "Mbox send fail %d\n", ret);
  1448. goto fail;
  1449. }
  1450. resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->xfer_buf;
  1451. if (!ti_sci_is_response_ack(resp))
  1452. ret = -ENODEV;
  1453. else
  1454. *freq = resp->freq_hz;
  1455. fail:
  1456. ti_sci_put_one_xfer(&info->minfo, xfer);
  1457. return ret;
  1458. }
  1459. /**
  1460. * ti_sci_cmd_prepare_sleep() - Prepare system for system suspend
  1461. * @handle: pointer to TI SCI handle
  1462. * @mode: Device identifier
  1463. * @ctx_lo: Low part of address for context save
  1464. * @ctx_hi: High part of address for context save
  1465. * @debug_flags: Debug flags to pass to firmware
  1466. *
  1467. * Return: 0 if all went well, else returns appropriate error value.
  1468. */
  1469. static int ti_sci_cmd_prepare_sleep(const struct ti_sci_handle *handle, u8 mode,
  1470. u32 ctx_lo, u32 ctx_hi, u32 debug_flags)
  1471. {
  1472. u32 msg_flags = mode == TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO ?
  1473. TI_SCI_FLAG_REQ_GENERIC_NORESPONSE :
  1474. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
  1475. struct ti_sci_info *info;
  1476. struct ti_sci_msg_req_prepare_sleep *req;
  1477. struct ti_sci_msg_hdr *resp;
  1478. struct ti_sci_xfer *xfer;
  1479. struct device *dev;
  1480. int ret = 0;
  1481. if (IS_ERR(handle))
  1482. return PTR_ERR(handle);
  1483. if (!handle)
  1484. return -EINVAL;
  1485. info = handle_to_ti_sci_info(handle);
  1486. dev = info->dev;
  1487. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PREPARE_SLEEP,
  1488. msg_flags,
  1489. sizeof(*req), sizeof(*resp));
  1490. if (IS_ERR(xfer)) {
  1491. ret = PTR_ERR(xfer);
  1492. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1493. return ret;
  1494. }
  1495. req = (struct ti_sci_msg_req_prepare_sleep *)xfer->xfer_buf;
  1496. req->mode = mode;
  1497. req->ctx_lo = ctx_lo;
  1498. req->ctx_hi = ctx_hi;
  1499. req->debug_flags = debug_flags;
  1500. ret = ti_sci_do_xfer(info, xfer);
  1501. if (ret) {
  1502. dev_err(dev, "Mbox send fail %d\n", ret);
  1503. goto fail;
  1504. }
  1505. if (msg_flags == TI_SCI_FLAG_REQ_ACK_ON_PROCESSED) {
  1506. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  1507. if (!ti_sci_is_response_ack(resp)) {
  1508. dev_err(dev, "Failed to prepare sleep\n");
  1509. ret = -ENODEV;
  1510. }
  1511. }
  1512. fail:
  1513. ti_sci_put_one_xfer(&info->minfo, xfer);
  1514. return ret;
  1515. }
  1516. /**
  1517. * ti_sci_msg_cmd_query_fw_caps() - Get the FW/SoC capabilities
  1518. * @handle: Pointer to TI SCI handle
  1519. * @fw_caps: Each bit in fw_caps indicating one FW/SOC capability
  1520. *
  1521. * Check if the firmware supports any optional low power modes.
  1522. * Old revisions of TIFS (< 08.04) will NACK the request which results in
  1523. * -ENODEV being returned.
  1524. *
  1525. * Return: 0 if all went well, else returns appropriate error value.
  1526. */
  1527. static int ti_sci_msg_cmd_query_fw_caps(const struct ti_sci_handle *handle,
  1528. u64 *fw_caps)
  1529. {
  1530. struct ti_sci_info *info;
  1531. struct ti_sci_xfer *xfer;
  1532. struct ti_sci_msg_resp_query_fw_caps *resp;
  1533. struct device *dev;
  1534. int ret = 0;
  1535. if (IS_ERR(handle))
  1536. return PTR_ERR(handle);
  1537. if (!handle)
  1538. return -EINVAL;
  1539. info = handle_to_ti_sci_info(handle);
  1540. dev = info->dev;
  1541. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_QUERY_FW_CAPS,
  1542. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1543. sizeof(struct ti_sci_msg_hdr),
  1544. sizeof(*resp));
  1545. if (IS_ERR(xfer)) {
  1546. ret = PTR_ERR(xfer);
  1547. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1548. return ret;
  1549. }
  1550. ret = ti_sci_do_xfer(info, xfer);
  1551. if (ret) {
  1552. dev_err(dev, "Mbox send fail %d\n", ret);
  1553. goto fail;
  1554. }
  1555. resp = (struct ti_sci_msg_resp_query_fw_caps *)xfer->xfer_buf;
  1556. if (!ti_sci_is_response_ack(resp)) {
  1557. dev_err(dev, "Failed to get capabilities\n");
  1558. ret = -ENODEV;
  1559. goto fail;
  1560. }
  1561. if (fw_caps)
  1562. *fw_caps = resp->fw_caps;
  1563. fail:
  1564. ti_sci_put_one_xfer(&info->minfo, xfer);
  1565. return ret;
  1566. }
  1567. /**
  1568. * ti_sci_cmd_set_io_isolation() - Enable IO isolation in LPM
  1569. * @handle: Pointer to TI SCI handle
  1570. * @state: The desired state of the IO isolation
  1571. *
  1572. * Return: 0 if all went well, else returns appropriate error value.
  1573. */
  1574. static int ti_sci_cmd_set_io_isolation(const struct ti_sci_handle *handle,
  1575. u8 state)
  1576. {
  1577. struct ti_sci_info *info;
  1578. struct ti_sci_msg_req_set_io_isolation *req;
  1579. struct ti_sci_msg_hdr *resp;
  1580. struct ti_sci_xfer *xfer;
  1581. struct device *dev;
  1582. int ret = 0;
  1583. if (IS_ERR(handle))
  1584. return PTR_ERR(handle);
  1585. if (!handle)
  1586. return -EINVAL;
  1587. info = handle_to_ti_sci_info(handle);
  1588. dev = info->dev;
  1589. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_IO_ISOLATION,
  1590. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1591. sizeof(*req), sizeof(*resp));
  1592. if (IS_ERR(xfer)) {
  1593. ret = PTR_ERR(xfer);
  1594. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1595. return ret;
  1596. }
  1597. req = (struct ti_sci_msg_req_set_io_isolation *)xfer->xfer_buf;
  1598. req->state = state;
  1599. ret = ti_sci_do_xfer(info, xfer);
  1600. if (ret) {
  1601. dev_err(dev, "Mbox send fail %d\n", ret);
  1602. goto fail;
  1603. }
  1604. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  1605. if (!ti_sci_is_response_ack(resp)) {
  1606. dev_err(dev, "Failed to set IO isolation\n");
  1607. ret = -ENODEV;
  1608. }
  1609. fail:
  1610. ti_sci_put_one_xfer(&info->minfo, xfer);
  1611. return ret;
  1612. }
  1613. /**
  1614. * ti_sci_msg_cmd_lpm_wake_reason() - Get the wakeup source from LPM
  1615. * @handle: Pointer to TI SCI handle
  1616. * @source: The wakeup source that woke the SoC from LPM
  1617. * @timestamp: Timestamp of the wakeup event
  1618. * @pin: The pin that has triggered wake up
  1619. * @mode: The last entered low power mode
  1620. *
  1621. * Return: 0 if all went well, else returns appropriate error value.
  1622. */
  1623. static int ti_sci_msg_cmd_lpm_wake_reason(const struct ti_sci_handle *handle,
  1624. u32 *source, u64 *timestamp, u8 *pin, u8 *mode)
  1625. {
  1626. struct ti_sci_info *info;
  1627. struct ti_sci_xfer *xfer;
  1628. struct ti_sci_msg_resp_lpm_wake_reason *resp;
  1629. struct device *dev;
  1630. int ret = 0;
  1631. if (IS_ERR(handle))
  1632. return PTR_ERR(handle);
  1633. if (!handle)
  1634. return -EINVAL;
  1635. info = handle_to_ti_sci_info(handle);
  1636. dev = info->dev;
  1637. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_WAKE_REASON,
  1638. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1639. sizeof(struct ti_sci_msg_hdr),
  1640. sizeof(*resp));
  1641. if (IS_ERR(xfer)) {
  1642. ret = PTR_ERR(xfer);
  1643. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1644. return ret;
  1645. }
  1646. ret = ti_sci_do_xfer(info, xfer);
  1647. if (ret) {
  1648. dev_err(dev, "Mbox send fail %d\n", ret);
  1649. goto fail;
  1650. }
  1651. resp = (struct ti_sci_msg_resp_lpm_wake_reason *)xfer->xfer_buf;
  1652. if (!ti_sci_is_response_ack(resp)) {
  1653. dev_err(dev, "Failed to get wake reason\n");
  1654. ret = -ENODEV;
  1655. goto fail;
  1656. }
  1657. if (source)
  1658. *source = resp->wake_source;
  1659. if (timestamp)
  1660. *timestamp = resp->wake_timestamp;
  1661. if (pin)
  1662. *pin = resp->wake_pin;
  1663. if (mode)
  1664. *mode = resp->mode;
  1665. fail:
  1666. ti_sci_put_one_xfer(&info->minfo, xfer);
  1667. return ret;
  1668. }
  1669. /**
  1670. * ti_sci_cmd_set_device_constraint() - Set LPM constraint on behalf of a device
  1671. * @handle: pointer to TI SCI handle
  1672. * @id: Device identifier
  1673. * @state: The desired state of device constraint: set or clear
  1674. *
  1675. * Return: 0 if all went well, else returns appropriate error value.
  1676. */
  1677. static int ti_sci_cmd_set_device_constraint(const struct ti_sci_handle *handle,
  1678. u32 id, u8 state)
  1679. {
  1680. struct ti_sci_info *info;
  1681. struct ti_sci_msg_req_lpm_set_device_constraint *req;
  1682. struct ti_sci_msg_hdr *resp;
  1683. struct ti_sci_xfer *xfer;
  1684. struct device *dev;
  1685. int ret = 0;
  1686. if (IS_ERR(handle))
  1687. return PTR_ERR(handle);
  1688. if (!handle)
  1689. return -EINVAL;
  1690. info = handle_to_ti_sci_info(handle);
  1691. dev = info->dev;
  1692. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_SET_DEVICE_CONSTRAINT,
  1693. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1694. sizeof(*req), sizeof(*resp));
  1695. if (IS_ERR(xfer)) {
  1696. ret = PTR_ERR(xfer);
  1697. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1698. return ret;
  1699. }
  1700. req = (struct ti_sci_msg_req_lpm_set_device_constraint *)xfer->xfer_buf;
  1701. req->id = id;
  1702. req->state = state;
  1703. ret = ti_sci_do_xfer(info, xfer);
  1704. if (ret) {
  1705. dev_err(dev, "Mbox send fail %d\n", ret);
  1706. goto fail;
  1707. }
  1708. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  1709. if (!ti_sci_is_response_ack(resp)) {
  1710. dev_err(dev, "Failed to set device constraint\n");
  1711. ret = -ENODEV;
  1712. }
  1713. fail:
  1714. ti_sci_put_one_xfer(&info->minfo, xfer);
  1715. return ret;
  1716. }
  1717. /**
  1718. * ti_sci_cmd_set_latency_constraint() - Set LPM resume latency constraint
  1719. * @handle: pointer to TI SCI handle
  1720. * @latency: maximum acceptable latency (in ms) to wake up from LPM
  1721. * @state: The desired state of latency constraint: set or clear
  1722. *
  1723. * Return: 0 if all went well, else returns appropriate error value.
  1724. */
  1725. static int ti_sci_cmd_set_latency_constraint(const struct ti_sci_handle *handle,
  1726. u16 latency, u8 state)
  1727. {
  1728. struct ti_sci_info *info;
  1729. struct ti_sci_msg_req_lpm_set_latency_constraint *req;
  1730. struct ti_sci_msg_hdr *resp;
  1731. struct ti_sci_xfer *xfer;
  1732. struct device *dev;
  1733. int ret = 0;
  1734. if (IS_ERR(handle))
  1735. return PTR_ERR(handle);
  1736. if (!handle)
  1737. return -EINVAL;
  1738. info = handle_to_ti_sci_info(handle);
  1739. dev = info->dev;
  1740. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_SET_LATENCY_CONSTRAINT,
  1741. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1742. sizeof(*req), sizeof(*resp));
  1743. if (IS_ERR(xfer)) {
  1744. ret = PTR_ERR(xfer);
  1745. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1746. return ret;
  1747. }
  1748. req = (struct ti_sci_msg_req_lpm_set_latency_constraint *)xfer->xfer_buf;
  1749. req->latency = latency;
  1750. req->state = state;
  1751. ret = ti_sci_do_xfer(info, xfer);
  1752. if (ret) {
  1753. dev_err(dev, "Mbox send fail %d\n", ret);
  1754. goto fail;
  1755. }
  1756. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  1757. if (!ti_sci_is_response_ack(resp)) {
  1758. dev_err(dev, "Failed to set device constraint\n");
  1759. ret = -ENODEV;
  1760. }
  1761. fail:
  1762. ti_sci_put_one_xfer(&info->minfo, xfer);
  1763. return ret;
  1764. }
  1765. /**
  1766. * ti_sci_cmd_lpm_abort() - Abort entry to LPM by clearing selection of LPM to enter
  1767. * @dev: Device pointer corresponding to the SCI entity
  1768. *
  1769. * Return: 0 if all went well, else returns appropriate error value.
  1770. */
  1771. static int ti_sci_cmd_lpm_abort(struct device *dev)
  1772. {
  1773. struct ti_sci_info *info = dev_get_drvdata(dev);
  1774. struct ti_sci_msg_hdr *req;
  1775. struct ti_sci_msg_hdr *resp;
  1776. struct ti_sci_xfer *xfer;
  1777. int ret = 0;
  1778. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_ABORT,
  1779. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1780. sizeof(*req), sizeof(*resp));
  1781. if (IS_ERR(xfer)) {
  1782. ret = PTR_ERR(xfer);
  1783. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1784. return ret;
  1785. }
  1786. req = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  1787. ret = ti_sci_do_xfer(info, xfer);
  1788. if (ret) {
  1789. dev_err(dev, "Mbox send fail %d\n", ret);
  1790. goto fail;
  1791. }
  1792. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  1793. if (!ti_sci_is_response_ack(resp))
  1794. ret = -ENODEV;
  1795. fail:
  1796. ti_sci_put_one_xfer(&info->minfo, xfer);
  1797. return ret;
  1798. }
  1799. static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
  1800. {
  1801. struct ti_sci_info *info;
  1802. struct ti_sci_msg_req_reboot *req;
  1803. struct ti_sci_msg_hdr *resp;
  1804. struct ti_sci_xfer *xfer;
  1805. struct device *dev;
  1806. int ret = 0;
  1807. if (IS_ERR(handle))
  1808. return PTR_ERR(handle);
  1809. if (!handle)
  1810. return -EINVAL;
  1811. info = handle_to_ti_sci_info(handle);
  1812. dev = info->dev;
  1813. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SYS_RESET,
  1814. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1815. sizeof(*req), sizeof(*resp));
  1816. if (IS_ERR(xfer)) {
  1817. ret = PTR_ERR(xfer);
  1818. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1819. return ret;
  1820. }
  1821. req = (struct ti_sci_msg_req_reboot *)xfer->xfer_buf;
  1822. ret = ti_sci_do_xfer(info, xfer);
  1823. if (ret) {
  1824. dev_err(dev, "Mbox send fail %d\n", ret);
  1825. goto fail;
  1826. }
  1827. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  1828. if (!ti_sci_is_response_ack(resp))
  1829. ret = -ENODEV;
  1830. else
  1831. ret = 0;
  1832. fail:
  1833. ti_sci_put_one_xfer(&info->minfo, xfer);
  1834. return ret;
  1835. }
  1836. /**
  1837. * ti_sci_get_resource_range - Helper to get a range of resources assigned
  1838. * to a host. Resource is uniquely identified by
  1839. * type and subtype.
  1840. * @handle: Pointer to TISCI handle.
  1841. * @dev_id: TISCI device ID.
  1842. * @subtype: Resource assignment subtype that is being requested
  1843. * from the given device.
  1844. * @s_host: Host processor ID to which the resources are allocated
  1845. * @desc: Pointer to ti_sci_resource_desc to be updated with the
  1846. * resource range start index and number of resources
  1847. *
  1848. * Return: 0 if all went fine, else return appropriate error.
  1849. */
  1850. static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
  1851. u32 dev_id, u8 subtype, u8 s_host,
  1852. struct ti_sci_resource_desc *desc)
  1853. {
  1854. struct ti_sci_msg_resp_get_resource_range *resp;
  1855. struct ti_sci_msg_req_get_resource_range *req;
  1856. struct ti_sci_xfer *xfer;
  1857. struct ti_sci_info *info;
  1858. struct device *dev;
  1859. int ret = 0;
  1860. if (IS_ERR(handle))
  1861. return PTR_ERR(handle);
  1862. if (!handle || !desc)
  1863. return -EINVAL;
  1864. info = handle_to_ti_sci_info(handle);
  1865. dev = info->dev;
  1866. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE,
  1867. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1868. sizeof(*req), sizeof(*resp));
  1869. if (IS_ERR(xfer)) {
  1870. ret = PTR_ERR(xfer);
  1871. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1872. return ret;
  1873. }
  1874. req = (struct ti_sci_msg_req_get_resource_range *)xfer->xfer_buf;
  1875. req->secondary_host = s_host;
  1876. req->type = dev_id & MSG_RM_RESOURCE_TYPE_MASK;
  1877. req->subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
  1878. ret = ti_sci_do_xfer(info, xfer);
  1879. if (ret) {
  1880. dev_err(dev, "Mbox send fail %d\n", ret);
  1881. goto fail;
  1882. }
  1883. resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->xfer_buf;
  1884. if (!ti_sci_is_response_ack(resp)) {
  1885. ret = -ENODEV;
  1886. } else if (!resp->range_num && !resp->range_num_sec) {
  1887. /* Neither of the two resource range is valid */
  1888. ret = -ENODEV;
  1889. } else {
  1890. desc->start = resp->range_start;
  1891. desc->num = resp->range_num;
  1892. desc->start_sec = resp->range_start_sec;
  1893. desc->num_sec = resp->range_num_sec;
  1894. }
  1895. fail:
  1896. ti_sci_put_one_xfer(&info->minfo, xfer);
  1897. return ret;
  1898. }
  1899. /**
  1900. * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host
  1901. * that is same as ti sci interface host.
  1902. * @handle: Pointer to TISCI handle.
  1903. * @dev_id: TISCI device ID.
  1904. * @subtype: Resource assignment subtype that is being requested
  1905. * from the given device.
  1906. * @desc: Pointer to ti_sci_resource_desc to be updated with the
  1907. * resource range start index and number of resources
  1908. *
  1909. * Return: 0 if all went fine, else return appropriate error.
  1910. */
  1911. static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
  1912. u32 dev_id, u8 subtype,
  1913. struct ti_sci_resource_desc *desc)
  1914. {
  1915. return ti_sci_get_resource_range(handle, dev_id, subtype,
  1916. TI_SCI_IRQ_SECONDARY_HOST_INVALID,
  1917. desc);
  1918. }
  1919. /**
  1920. * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources
  1921. * assigned to a specified host.
  1922. * @handle: Pointer to TISCI handle.
  1923. * @dev_id: TISCI device ID.
  1924. * @subtype: Resource assignment subtype that is being requested
  1925. * from the given device.
  1926. * @s_host: Host processor ID to which the resources are allocated
  1927. * @desc: Pointer to ti_sci_resource_desc to be updated with the
  1928. * resource range start index and number of resources
  1929. *
  1930. * Return: 0 if all went fine, else return appropriate error.
  1931. */
  1932. static
  1933. int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
  1934. u32 dev_id, u8 subtype, u8 s_host,
  1935. struct ti_sci_resource_desc *desc)
  1936. {
  1937. return ti_sci_get_resource_range(handle, dev_id, subtype, s_host, desc);
  1938. }
  1939. /**
  1940. * ti_sci_manage_irq() - Helper api to configure/release the irq route between
  1941. * the requested source and destination
  1942. * @handle: Pointer to TISCI handle.
  1943. * @valid_params: Bit fields defining the validity of certain params
  1944. * @src_id: Device ID of the IRQ source
  1945. * @src_index: IRQ source index within the source device
  1946. * @dst_id: Device ID of the IRQ destination
  1947. * @dst_host_irq: IRQ number of the destination device
  1948. * @ia_id: Device ID of the IA, if the IRQ flows through this IA
  1949. * @vint: Virtual interrupt to be used within the IA
  1950. * @global_event: Global event number to be used for the requesting event
  1951. * @vint_status_bit: Virtual interrupt status bit to be used for the event
  1952. * @s_host: Secondary host ID to which the irq/event is being
  1953. * requested for.
  1954. * @type: Request type irq set or release.
  1955. *
  1956. * Return: 0 if all went fine, else return appropriate error.
  1957. */
  1958. static int ti_sci_manage_irq(const struct ti_sci_handle *handle,
  1959. u32 valid_params, u16 src_id, u16 src_index,
  1960. u16 dst_id, u16 dst_host_irq, u16 ia_id, u16 vint,
  1961. u16 global_event, u8 vint_status_bit, u8 s_host,
  1962. u16 type)
  1963. {
  1964. struct ti_sci_msg_req_manage_irq *req;
  1965. struct ti_sci_msg_hdr *resp;
  1966. struct ti_sci_xfer *xfer;
  1967. struct ti_sci_info *info;
  1968. struct device *dev;
  1969. int ret = 0;
  1970. if (IS_ERR(handle))
  1971. return PTR_ERR(handle);
  1972. if (!handle)
  1973. return -EINVAL;
  1974. info = handle_to_ti_sci_info(handle);
  1975. dev = info->dev;
  1976. xfer = ti_sci_get_one_xfer(info, type, TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  1977. sizeof(*req), sizeof(*resp));
  1978. if (IS_ERR(xfer)) {
  1979. ret = PTR_ERR(xfer);
  1980. dev_err(dev, "Message alloc failed(%d)\n", ret);
  1981. return ret;
  1982. }
  1983. req = (struct ti_sci_msg_req_manage_irq *)xfer->xfer_buf;
  1984. req->valid_params = valid_params;
  1985. req->src_id = src_id;
  1986. req->src_index = src_index;
  1987. req->dst_id = dst_id;
  1988. req->dst_host_irq = dst_host_irq;
  1989. req->ia_id = ia_id;
  1990. req->vint = vint;
  1991. req->global_event = global_event;
  1992. req->vint_status_bit = vint_status_bit;
  1993. req->secondary_host = s_host;
  1994. ret = ti_sci_do_xfer(info, xfer);
  1995. if (ret) {
  1996. dev_err(dev, "Mbox send fail %d\n", ret);
  1997. goto fail;
  1998. }
  1999. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  2000. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  2001. fail:
  2002. ti_sci_put_one_xfer(&info->minfo, xfer);
  2003. return ret;
  2004. }
  2005. /**
  2006. * ti_sci_set_irq() - Helper api to configure the irq route between the
  2007. * requested source and destination
  2008. * @handle: Pointer to TISCI handle.
  2009. * @valid_params: Bit fields defining the validity of certain params
  2010. * @src_id: Device ID of the IRQ source
  2011. * @src_index: IRQ source index within the source device
  2012. * @dst_id: Device ID of the IRQ destination
  2013. * @dst_host_irq: IRQ number of the destination device
  2014. * @ia_id: Device ID of the IA, if the IRQ flows through this IA
  2015. * @vint: Virtual interrupt to be used within the IA
  2016. * @global_event: Global event number to be used for the requesting event
  2017. * @vint_status_bit: Virtual interrupt status bit to be used for the event
  2018. * @s_host: Secondary host ID to which the irq/event is being
  2019. * requested for.
  2020. *
  2021. * Return: 0 if all went fine, else return appropriate error.
  2022. */
  2023. static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params,
  2024. u16 src_id, u16 src_index, u16 dst_id,
  2025. u16 dst_host_irq, u16 ia_id, u16 vint,
  2026. u16 global_event, u8 vint_status_bit, u8 s_host)
  2027. {
  2028. pr_debug("%s: IRQ set with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
  2029. __func__, valid_params, src_id, src_index,
  2030. dst_id, dst_host_irq, ia_id, vint, global_event,
  2031. vint_status_bit);
  2032. return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
  2033. dst_id, dst_host_irq, ia_id, vint,
  2034. global_event, vint_status_bit, s_host,
  2035. TI_SCI_MSG_SET_IRQ);
  2036. }
  2037. /**
  2038. * ti_sci_free_irq() - Helper api to free the irq route between the
  2039. * requested source and destination
  2040. * @handle: Pointer to TISCI handle.
  2041. * @valid_params: Bit fields defining the validity of certain params
  2042. * @src_id: Device ID of the IRQ source
  2043. * @src_index: IRQ source index within the source device
  2044. * @dst_id: Device ID of the IRQ destination
  2045. * @dst_host_irq: IRQ number of the destination device
  2046. * @ia_id: Device ID of the IA, if the IRQ flows through this IA
  2047. * @vint: Virtual interrupt to be used within the IA
  2048. * @global_event: Global event number to be used for the requesting event
  2049. * @vint_status_bit: Virtual interrupt status bit to be used for the event
  2050. * @s_host: Secondary host ID to which the irq/event is being
  2051. * requested for.
  2052. *
  2053. * Return: 0 if all went fine, else return appropriate error.
  2054. */
  2055. static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params,
  2056. u16 src_id, u16 src_index, u16 dst_id,
  2057. u16 dst_host_irq, u16 ia_id, u16 vint,
  2058. u16 global_event, u8 vint_status_bit, u8 s_host)
  2059. {
  2060. pr_debug("%s: IRQ release with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
  2061. __func__, valid_params, src_id, src_index,
  2062. dst_id, dst_host_irq, ia_id, vint, global_event,
  2063. vint_status_bit);
  2064. return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
  2065. dst_id, dst_host_irq, ia_id, vint,
  2066. global_event, vint_status_bit, s_host,
  2067. TI_SCI_MSG_FREE_IRQ);
  2068. }
  2069. /**
  2070. * ti_sci_cmd_set_irq() - Configure a host irq route between the requested
  2071. * source and destination.
  2072. * @handle: Pointer to TISCI handle.
  2073. * @src_id: Device ID of the IRQ source
  2074. * @src_index: IRQ source index within the source device
  2075. * @dst_id: Device ID of the IRQ destination
  2076. * @dst_host_irq: IRQ number of the destination device
  2077. *
  2078. * Return: 0 if all went fine, else return appropriate error.
  2079. */
  2080. static int ti_sci_cmd_set_irq(const struct ti_sci_handle *handle, u16 src_id,
  2081. u16 src_index, u16 dst_id, u16 dst_host_irq)
  2082. {
  2083. u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
  2084. return ti_sci_set_irq(handle, valid_params, src_id, src_index, dst_id,
  2085. dst_host_irq, 0, 0, 0, 0, 0);
  2086. }
  2087. /**
  2088. * ti_sci_cmd_set_event_map() - Configure an event based irq route between the
  2089. * requested source and Interrupt Aggregator.
  2090. * @handle: Pointer to TISCI handle.
  2091. * @src_id: Device ID of the IRQ source
  2092. * @src_index: IRQ source index within the source device
  2093. * @ia_id: Device ID of the IA, if the IRQ flows through this IA
  2094. * @vint: Virtual interrupt to be used within the IA
  2095. * @global_event: Global event number to be used for the requesting event
  2096. * @vint_status_bit: Virtual interrupt status bit to be used for the event
  2097. *
  2098. * Return: 0 if all went fine, else return appropriate error.
  2099. */
  2100. static int ti_sci_cmd_set_event_map(const struct ti_sci_handle *handle,
  2101. u16 src_id, u16 src_index, u16 ia_id,
  2102. u16 vint, u16 global_event,
  2103. u8 vint_status_bit)
  2104. {
  2105. u32 valid_params = MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID |
  2106. MSG_FLAG_GLB_EVNT_VALID |
  2107. MSG_FLAG_VINT_STS_BIT_VALID;
  2108. return ti_sci_set_irq(handle, valid_params, src_id, src_index, 0, 0,
  2109. ia_id, vint, global_event, vint_status_bit, 0);
  2110. }
  2111. /**
  2112. * ti_sci_cmd_free_irq() - Free a host irq route between the between the
  2113. * requested source and destination.
  2114. * @handle: Pointer to TISCI handle.
  2115. * @src_id: Device ID of the IRQ source
  2116. * @src_index: IRQ source index within the source device
  2117. * @dst_id: Device ID of the IRQ destination
  2118. * @dst_host_irq: IRQ number of the destination device
  2119. *
  2120. * Return: 0 if all went fine, else return appropriate error.
  2121. */
  2122. static int ti_sci_cmd_free_irq(const struct ti_sci_handle *handle, u16 src_id,
  2123. u16 src_index, u16 dst_id, u16 dst_host_irq)
  2124. {
  2125. u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
  2126. return ti_sci_free_irq(handle, valid_params, src_id, src_index, dst_id,
  2127. dst_host_irq, 0, 0, 0, 0, 0);
  2128. }
  2129. /**
  2130. * ti_sci_cmd_free_event_map() - Free an event map between the requested source
  2131. * and Interrupt Aggregator.
  2132. * @handle: Pointer to TISCI handle.
  2133. * @src_id: Device ID of the IRQ source
  2134. * @src_index: IRQ source index within the source device
  2135. * @ia_id: Device ID of the IA, if the IRQ flows through this IA
  2136. * @vint: Virtual interrupt to be used within the IA
  2137. * @global_event: Global event number to be used for the requesting event
  2138. * @vint_status_bit: Virtual interrupt status bit to be used for the event
  2139. *
  2140. * Return: 0 if all went fine, else return appropriate error.
  2141. */
  2142. static int ti_sci_cmd_free_event_map(const struct ti_sci_handle *handle,
  2143. u16 src_id, u16 src_index, u16 ia_id,
  2144. u16 vint, u16 global_event,
  2145. u8 vint_status_bit)
  2146. {
  2147. u32 valid_params = MSG_FLAG_IA_ID_VALID |
  2148. MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID |
  2149. MSG_FLAG_VINT_STS_BIT_VALID;
  2150. return ti_sci_free_irq(handle, valid_params, src_id, src_index, 0, 0,
  2151. ia_id, vint, global_event, vint_status_bit, 0);
  2152. }
  2153. /**
  2154. * ti_sci_cmd_rm_ring_cfg() - Configure a NAVSS ring
  2155. * @handle: Pointer to TI SCI handle.
  2156. * @params: Pointer to ti_sci_msg_rm_ring_cfg ring config structure
  2157. *
  2158. * Return: 0 if all went well, else returns appropriate error value.
  2159. *
  2160. * See @ti_sci_msg_rm_ring_cfg and @ti_sci_msg_rm_ring_cfg_req for
  2161. * more info.
  2162. */
  2163. static int ti_sci_cmd_rm_ring_cfg(const struct ti_sci_handle *handle,
  2164. const struct ti_sci_msg_rm_ring_cfg *params)
  2165. {
  2166. struct ti_sci_msg_rm_ring_cfg_req *req;
  2167. struct ti_sci_msg_hdr *resp;
  2168. struct ti_sci_xfer *xfer;
  2169. struct ti_sci_info *info;
  2170. struct device *dev;
  2171. int ret = 0;
  2172. if (IS_ERR_OR_NULL(handle))
  2173. return -EINVAL;
  2174. info = handle_to_ti_sci_info(handle);
  2175. dev = info->dev;
  2176. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_RING_CFG,
  2177. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2178. sizeof(*req), sizeof(*resp));
  2179. if (IS_ERR(xfer)) {
  2180. ret = PTR_ERR(xfer);
  2181. dev_err(dev, "RM_RA:Message config failed(%d)\n", ret);
  2182. return ret;
  2183. }
  2184. req = (struct ti_sci_msg_rm_ring_cfg_req *)xfer->xfer_buf;
  2185. req->valid_params = params->valid_params;
  2186. req->nav_id = params->nav_id;
  2187. req->index = params->index;
  2188. req->addr_lo = params->addr_lo;
  2189. req->addr_hi = params->addr_hi;
  2190. req->count = params->count;
  2191. req->mode = params->mode;
  2192. req->size = params->size;
  2193. req->order_id = params->order_id;
  2194. req->virtid = params->virtid;
  2195. req->asel = params->asel;
  2196. ret = ti_sci_do_xfer(info, xfer);
  2197. if (ret) {
  2198. dev_err(dev, "RM_RA:Mbox config send fail %d\n", ret);
  2199. goto fail;
  2200. }
  2201. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  2202. ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
  2203. fail:
  2204. ti_sci_put_one_xfer(&info->minfo, xfer);
  2205. dev_dbg(dev, "RM_RA:config ring %u ret:%d\n", params->index, ret);
  2206. return ret;
  2207. }
  2208. /**
  2209. * ti_sci_cmd_rm_psil_pair() - Pair PSI-L source to destination thread
  2210. * @handle: Pointer to TI SCI handle.
  2211. * @nav_id: Device ID of Navigator Subsystem which should be used for
  2212. * pairing
  2213. * @src_thread: Source PSI-L thread ID
  2214. * @dst_thread: Destination PSI-L thread ID
  2215. *
  2216. * Return: 0 if all went well, else returns appropriate error value.
  2217. */
  2218. static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
  2219. u32 nav_id, u32 src_thread, u32 dst_thread)
  2220. {
  2221. struct ti_sci_msg_psil_pair *req;
  2222. struct ti_sci_msg_hdr *resp;
  2223. struct ti_sci_xfer *xfer;
  2224. struct ti_sci_info *info;
  2225. struct device *dev;
  2226. int ret = 0;
  2227. if (IS_ERR(handle))
  2228. return PTR_ERR(handle);
  2229. if (!handle)
  2230. return -EINVAL;
  2231. info = handle_to_ti_sci_info(handle);
  2232. dev = info->dev;
  2233. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_PSIL_PAIR,
  2234. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2235. sizeof(*req), sizeof(*resp));
  2236. if (IS_ERR(xfer)) {
  2237. ret = PTR_ERR(xfer);
  2238. dev_err(dev, "RM_PSIL:Message reconfig failed(%d)\n", ret);
  2239. return ret;
  2240. }
  2241. req = (struct ti_sci_msg_psil_pair *)xfer->xfer_buf;
  2242. req->nav_id = nav_id;
  2243. req->src_thread = src_thread;
  2244. req->dst_thread = dst_thread;
  2245. ret = ti_sci_do_xfer(info, xfer);
  2246. if (ret) {
  2247. dev_err(dev, "RM_PSIL:Mbox send fail %d\n", ret);
  2248. goto fail;
  2249. }
  2250. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  2251. ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
  2252. fail:
  2253. ti_sci_put_one_xfer(&info->minfo, xfer);
  2254. return ret;
  2255. }
  2256. /**
  2257. * ti_sci_cmd_rm_psil_unpair() - Unpair PSI-L source from destination thread
  2258. * @handle: Pointer to TI SCI handle.
  2259. * @nav_id: Device ID of Navigator Subsystem which should be used for
  2260. * unpairing
  2261. * @src_thread: Source PSI-L thread ID
  2262. * @dst_thread: Destination PSI-L thread ID
  2263. *
  2264. * Return: 0 if all went well, else returns appropriate error value.
  2265. */
  2266. static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle,
  2267. u32 nav_id, u32 src_thread, u32 dst_thread)
  2268. {
  2269. struct ti_sci_msg_psil_unpair *req;
  2270. struct ti_sci_msg_hdr *resp;
  2271. struct ti_sci_xfer *xfer;
  2272. struct ti_sci_info *info;
  2273. struct device *dev;
  2274. int ret = 0;
  2275. if (IS_ERR(handle))
  2276. return PTR_ERR(handle);
  2277. if (!handle)
  2278. return -EINVAL;
  2279. info = handle_to_ti_sci_info(handle);
  2280. dev = info->dev;
  2281. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_PSIL_UNPAIR,
  2282. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2283. sizeof(*req), sizeof(*resp));
  2284. if (IS_ERR(xfer)) {
  2285. ret = PTR_ERR(xfer);
  2286. dev_err(dev, "RM_PSIL:Message reconfig failed(%d)\n", ret);
  2287. return ret;
  2288. }
  2289. req = (struct ti_sci_msg_psil_unpair *)xfer->xfer_buf;
  2290. req->nav_id = nav_id;
  2291. req->src_thread = src_thread;
  2292. req->dst_thread = dst_thread;
  2293. ret = ti_sci_do_xfer(info, xfer);
  2294. if (ret) {
  2295. dev_err(dev, "RM_PSIL:Mbox send fail %d\n", ret);
  2296. goto fail;
  2297. }
  2298. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  2299. ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
  2300. fail:
  2301. ti_sci_put_one_xfer(&info->minfo, xfer);
  2302. return ret;
  2303. }
  2304. /**
  2305. * ti_sci_cmd_rm_udmap_tx_ch_cfg() - Configure a UDMAP TX channel
  2306. * @handle: Pointer to TI SCI handle.
  2307. * @params: Pointer to ti_sci_msg_rm_udmap_tx_ch_cfg TX channel config
  2308. * structure
  2309. *
  2310. * Return: 0 if all went well, else returns appropriate error value.
  2311. *
  2312. * See @ti_sci_msg_rm_udmap_tx_ch_cfg and @ti_sci_msg_rm_udmap_tx_ch_cfg_req for
  2313. * more info.
  2314. */
  2315. static int ti_sci_cmd_rm_udmap_tx_ch_cfg(const struct ti_sci_handle *handle,
  2316. const struct ti_sci_msg_rm_udmap_tx_ch_cfg *params)
  2317. {
  2318. struct ti_sci_msg_rm_udmap_tx_ch_cfg_req *req;
  2319. struct ti_sci_msg_hdr *resp;
  2320. struct ti_sci_xfer *xfer;
  2321. struct ti_sci_info *info;
  2322. struct device *dev;
  2323. int ret = 0;
  2324. if (IS_ERR_OR_NULL(handle))
  2325. return -EINVAL;
  2326. info = handle_to_ti_sci_info(handle);
  2327. dev = info->dev;
  2328. xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_TX_CH_CFG,
  2329. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2330. sizeof(*req), sizeof(*resp));
  2331. if (IS_ERR(xfer)) {
  2332. ret = PTR_ERR(xfer);
  2333. dev_err(dev, "Message TX_CH_CFG alloc failed(%d)\n", ret);
  2334. return ret;
  2335. }
  2336. req = (struct ti_sci_msg_rm_udmap_tx_ch_cfg_req *)xfer->xfer_buf;
  2337. req->valid_params = params->valid_params;
  2338. req->nav_id = params->nav_id;
  2339. req->index = params->index;
  2340. req->tx_pause_on_err = params->tx_pause_on_err;
  2341. req->tx_filt_einfo = params->tx_filt_einfo;
  2342. req->tx_filt_pswords = params->tx_filt_pswords;
  2343. req->tx_atype = params->tx_atype;
  2344. req->tx_chan_type = params->tx_chan_type;
  2345. req->tx_supr_tdpkt = params->tx_supr_tdpkt;
  2346. req->tx_fetch_size = params->tx_fetch_size;
  2347. req->tx_credit_count = params->tx_credit_count;
  2348. req->txcq_qnum = params->txcq_qnum;
  2349. req->tx_priority = params->tx_priority;
  2350. req->tx_qos = params->tx_qos;
  2351. req->tx_orderid = params->tx_orderid;
  2352. req->fdepth = params->fdepth;
  2353. req->tx_sched_priority = params->tx_sched_priority;
  2354. req->tx_burst_size = params->tx_burst_size;
  2355. req->tx_tdtype = params->tx_tdtype;
  2356. req->extended_ch_type = params->extended_ch_type;
  2357. ret = ti_sci_do_xfer(info, xfer);
  2358. if (ret) {
  2359. dev_err(dev, "Mbox send TX_CH_CFG fail %d\n", ret);
  2360. goto fail;
  2361. }
  2362. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  2363. ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
  2364. fail:
  2365. ti_sci_put_one_xfer(&info->minfo, xfer);
  2366. dev_dbg(dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret);
  2367. return ret;
  2368. }
  2369. /**
  2370. * ti_sci_cmd_rm_udmap_rx_ch_cfg() - Configure a UDMAP RX channel
  2371. * @handle: Pointer to TI SCI handle.
  2372. * @params: Pointer to ti_sci_msg_rm_udmap_rx_ch_cfg RX channel config
  2373. * structure
  2374. *
  2375. * Return: 0 if all went well, else returns appropriate error value.
  2376. *
  2377. * See @ti_sci_msg_rm_udmap_rx_ch_cfg and @ti_sci_msg_rm_udmap_rx_ch_cfg_req for
  2378. * more info.
  2379. */
  2380. static int ti_sci_cmd_rm_udmap_rx_ch_cfg(const struct ti_sci_handle *handle,
  2381. const struct ti_sci_msg_rm_udmap_rx_ch_cfg *params)
  2382. {
  2383. struct ti_sci_msg_rm_udmap_rx_ch_cfg_req *req;
  2384. struct ti_sci_msg_hdr *resp;
  2385. struct ti_sci_xfer *xfer;
  2386. struct ti_sci_info *info;
  2387. struct device *dev;
  2388. int ret = 0;
  2389. if (IS_ERR_OR_NULL(handle))
  2390. return -EINVAL;
  2391. info = handle_to_ti_sci_info(handle);
  2392. dev = info->dev;
  2393. xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_RX_CH_CFG,
  2394. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2395. sizeof(*req), sizeof(*resp));
  2396. if (IS_ERR(xfer)) {
  2397. ret = PTR_ERR(xfer);
  2398. dev_err(dev, "Message RX_CH_CFG alloc failed(%d)\n", ret);
  2399. return ret;
  2400. }
  2401. req = (struct ti_sci_msg_rm_udmap_rx_ch_cfg_req *)xfer->xfer_buf;
  2402. req->valid_params = params->valid_params;
  2403. req->nav_id = params->nav_id;
  2404. req->index = params->index;
  2405. req->rx_fetch_size = params->rx_fetch_size;
  2406. req->rxcq_qnum = params->rxcq_qnum;
  2407. req->rx_priority = params->rx_priority;
  2408. req->rx_qos = params->rx_qos;
  2409. req->rx_orderid = params->rx_orderid;
  2410. req->rx_sched_priority = params->rx_sched_priority;
  2411. req->flowid_start = params->flowid_start;
  2412. req->flowid_cnt = params->flowid_cnt;
  2413. req->rx_pause_on_err = params->rx_pause_on_err;
  2414. req->rx_atype = params->rx_atype;
  2415. req->rx_chan_type = params->rx_chan_type;
  2416. req->rx_ignore_short = params->rx_ignore_short;
  2417. req->rx_ignore_long = params->rx_ignore_long;
  2418. req->rx_burst_size = params->rx_burst_size;
  2419. ret = ti_sci_do_xfer(info, xfer);
  2420. if (ret) {
  2421. dev_err(dev, "Mbox send RX_CH_CFG fail %d\n", ret);
  2422. goto fail;
  2423. }
  2424. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  2425. ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
  2426. fail:
  2427. ti_sci_put_one_xfer(&info->minfo, xfer);
  2428. dev_dbg(dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret);
  2429. return ret;
  2430. }
  2431. /**
  2432. * ti_sci_cmd_rm_udmap_rx_flow_cfg() - Configure UDMAP RX FLOW
  2433. * @handle: Pointer to TI SCI handle.
  2434. * @params: Pointer to ti_sci_msg_rm_udmap_flow_cfg RX FLOW config
  2435. * structure
  2436. *
  2437. * Return: 0 if all went well, else returns appropriate error value.
  2438. *
  2439. * See @ti_sci_msg_rm_udmap_flow_cfg and @ti_sci_msg_rm_udmap_flow_cfg_req for
  2440. * more info.
  2441. */
  2442. static int ti_sci_cmd_rm_udmap_rx_flow_cfg(const struct ti_sci_handle *handle,
  2443. const struct ti_sci_msg_rm_udmap_flow_cfg *params)
  2444. {
  2445. struct ti_sci_msg_rm_udmap_flow_cfg_req *req;
  2446. struct ti_sci_msg_hdr *resp;
  2447. struct ti_sci_xfer *xfer;
  2448. struct ti_sci_info *info;
  2449. struct device *dev;
  2450. int ret = 0;
  2451. if (IS_ERR_OR_NULL(handle))
  2452. return -EINVAL;
  2453. info = handle_to_ti_sci_info(handle);
  2454. dev = info->dev;
  2455. xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_FLOW_CFG,
  2456. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2457. sizeof(*req), sizeof(*resp));
  2458. if (IS_ERR(xfer)) {
  2459. ret = PTR_ERR(xfer);
  2460. dev_err(dev, "RX_FL_CFG: Message alloc failed(%d)\n", ret);
  2461. return ret;
  2462. }
  2463. req = (struct ti_sci_msg_rm_udmap_flow_cfg_req *)xfer->xfer_buf;
  2464. req->valid_params = params->valid_params;
  2465. req->nav_id = params->nav_id;
  2466. req->flow_index = params->flow_index;
  2467. req->rx_einfo_present = params->rx_einfo_present;
  2468. req->rx_psinfo_present = params->rx_psinfo_present;
  2469. req->rx_error_handling = params->rx_error_handling;
  2470. req->rx_desc_type = params->rx_desc_type;
  2471. req->rx_sop_offset = params->rx_sop_offset;
  2472. req->rx_dest_qnum = params->rx_dest_qnum;
  2473. req->rx_src_tag_hi = params->rx_src_tag_hi;
  2474. req->rx_src_tag_lo = params->rx_src_tag_lo;
  2475. req->rx_dest_tag_hi = params->rx_dest_tag_hi;
  2476. req->rx_dest_tag_lo = params->rx_dest_tag_lo;
  2477. req->rx_src_tag_hi_sel = params->rx_src_tag_hi_sel;
  2478. req->rx_src_tag_lo_sel = params->rx_src_tag_lo_sel;
  2479. req->rx_dest_tag_hi_sel = params->rx_dest_tag_hi_sel;
  2480. req->rx_dest_tag_lo_sel = params->rx_dest_tag_lo_sel;
  2481. req->rx_fdq0_sz0_qnum = params->rx_fdq0_sz0_qnum;
  2482. req->rx_fdq1_qnum = params->rx_fdq1_qnum;
  2483. req->rx_fdq2_qnum = params->rx_fdq2_qnum;
  2484. req->rx_fdq3_qnum = params->rx_fdq3_qnum;
  2485. req->rx_ps_location = params->rx_ps_location;
  2486. ret = ti_sci_do_xfer(info, xfer);
  2487. if (ret) {
  2488. dev_err(dev, "RX_FL_CFG: Mbox send fail %d\n", ret);
  2489. goto fail;
  2490. }
  2491. resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
  2492. ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
  2493. fail:
  2494. ti_sci_put_one_xfer(&info->minfo, xfer);
  2495. dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret);
  2496. return ret;
  2497. }
  2498. /**
  2499. * ti_sci_cmd_proc_request() - Command to request a physical processor control
  2500. * @handle: Pointer to TI SCI handle
  2501. * @proc_id: Processor ID this request is for
  2502. *
  2503. * Return: 0 if all went well, else returns appropriate error value.
  2504. */
  2505. static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle,
  2506. u8 proc_id)
  2507. {
  2508. struct ti_sci_msg_req_proc_request *req;
  2509. struct ti_sci_msg_hdr *resp;
  2510. struct ti_sci_info *info;
  2511. struct ti_sci_xfer *xfer;
  2512. struct device *dev;
  2513. int ret = 0;
  2514. if (!handle)
  2515. return -EINVAL;
  2516. if (IS_ERR(handle))
  2517. return PTR_ERR(handle);
  2518. info = handle_to_ti_sci_info(handle);
  2519. dev = info->dev;
  2520. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_REQUEST,
  2521. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2522. sizeof(*req), sizeof(*resp));
  2523. if (IS_ERR(xfer)) {
  2524. ret = PTR_ERR(xfer);
  2525. dev_err(dev, "Message alloc failed(%d)\n", ret);
  2526. return ret;
  2527. }
  2528. req = (struct ti_sci_msg_req_proc_request *)xfer->xfer_buf;
  2529. req->processor_id = proc_id;
  2530. ret = ti_sci_do_xfer(info, xfer);
  2531. if (ret) {
  2532. dev_err(dev, "Mbox send fail %d\n", ret);
  2533. goto fail;
  2534. }
  2535. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  2536. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  2537. fail:
  2538. ti_sci_put_one_xfer(&info->minfo, xfer);
  2539. return ret;
  2540. }
  2541. /**
  2542. * ti_sci_cmd_proc_release() - Command to release a physical processor control
  2543. * @handle: Pointer to TI SCI handle
  2544. * @proc_id: Processor ID this request is for
  2545. *
  2546. * Return: 0 if all went well, else returns appropriate error value.
  2547. */
  2548. static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle,
  2549. u8 proc_id)
  2550. {
  2551. struct ti_sci_msg_req_proc_release *req;
  2552. struct ti_sci_msg_hdr *resp;
  2553. struct ti_sci_info *info;
  2554. struct ti_sci_xfer *xfer;
  2555. struct device *dev;
  2556. int ret = 0;
  2557. if (!handle)
  2558. return -EINVAL;
  2559. if (IS_ERR(handle))
  2560. return PTR_ERR(handle);
  2561. info = handle_to_ti_sci_info(handle);
  2562. dev = info->dev;
  2563. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_RELEASE,
  2564. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2565. sizeof(*req), sizeof(*resp));
  2566. if (IS_ERR(xfer)) {
  2567. ret = PTR_ERR(xfer);
  2568. dev_err(dev, "Message alloc failed(%d)\n", ret);
  2569. return ret;
  2570. }
  2571. req = (struct ti_sci_msg_req_proc_release *)xfer->xfer_buf;
  2572. req->processor_id = proc_id;
  2573. ret = ti_sci_do_xfer(info, xfer);
  2574. if (ret) {
  2575. dev_err(dev, "Mbox send fail %d\n", ret);
  2576. goto fail;
  2577. }
  2578. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  2579. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  2580. fail:
  2581. ti_sci_put_one_xfer(&info->minfo, xfer);
  2582. return ret;
  2583. }
  2584. /**
  2585. * ti_sci_cmd_proc_handover() - Command to handover a physical processor
  2586. * control to a host in the processor's access
  2587. * control list.
  2588. * @handle: Pointer to TI SCI handle
  2589. * @proc_id: Processor ID this request is for
  2590. * @host_id: Host ID to get the control of the processor
  2591. *
  2592. * Return: 0 if all went well, else returns appropriate error value.
  2593. */
  2594. static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle,
  2595. u8 proc_id, u8 host_id)
  2596. {
  2597. struct ti_sci_msg_req_proc_handover *req;
  2598. struct ti_sci_msg_hdr *resp;
  2599. struct ti_sci_info *info;
  2600. struct ti_sci_xfer *xfer;
  2601. struct device *dev;
  2602. int ret = 0;
  2603. if (!handle)
  2604. return -EINVAL;
  2605. if (IS_ERR(handle))
  2606. return PTR_ERR(handle);
  2607. info = handle_to_ti_sci_info(handle);
  2608. dev = info->dev;
  2609. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_HANDOVER,
  2610. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2611. sizeof(*req), sizeof(*resp));
  2612. if (IS_ERR(xfer)) {
  2613. ret = PTR_ERR(xfer);
  2614. dev_err(dev, "Message alloc failed(%d)\n", ret);
  2615. return ret;
  2616. }
  2617. req = (struct ti_sci_msg_req_proc_handover *)xfer->xfer_buf;
  2618. req->processor_id = proc_id;
  2619. req->host_id = host_id;
  2620. ret = ti_sci_do_xfer(info, xfer);
  2621. if (ret) {
  2622. dev_err(dev, "Mbox send fail %d\n", ret);
  2623. goto fail;
  2624. }
  2625. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  2626. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  2627. fail:
  2628. ti_sci_put_one_xfer(&info->minfo, xfer);
  2629. return ret;
  2630. }
  2631. /**
  2632. * ti_sci_cmd_proc_set_config() - Command to set the processor boot
  2633. * configuration flags
  2634. * @handle: Pointer to TI SCI handle
  2635. * @proc_id: Processor ID this request is for
  2636. * @bootvector: Processor Boot vector (start address)
  2637. * @config_flags_set: Configuration flags to be set
  2638. * @config_flags_clear: Configuration flags to be cleared.
  2639. *
  2640. * Return: 0 if all went well, else returns appropriate error value.
  2641. */
  2642. static int ti_sci_cmd_proc_set_config(const struct ti_sci_handle *handle,
  2643. u8 proc_id, u64 bootvector,
  2644. u32 config_flags_set,
  2645. u32 config_flags_clear)
  2646. {
  2647. struct ti_sci_msg_req_set_config *req;
  2648. struct ti_sci_msg_hdr *resp;
  2649. struct ti_sci_info *info;
  2650. struct ti_sci_xfer *xfer;
  2651. struct device *dev;
  2652. int ret = 0;
  2653. if (!handle)
  2654. return -EINVAL;
  2655. if (IS_ERR(handle))
  2656. return PTR_ERR(handle);
  2657. info = handle_to_ti_sci_info(handle);
  2658. dev = info->dev;
  2659. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CONFIG,
  2660. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2661. sizeof(*req), sizeof(*resp));
  2662. if (IS_ERR(xfer)) {
  2663. ret = PTR_ERR(xfer);
  2664. dev_err(dev, "Message alloc failed(%d)\n", ret);
  2665. return ret;
  2666. }
  2667. req = (struct ti_sci_msg_req_set_config *)xfer->xfer_buf;
  2668. req->processor_id = proc_id;
  2669. req->bootvector_low = bootvector & TI_SCI_ADDR_LOW_MASK;
  2670. req->bootvector_high = (bootvector & TI_SCI_ADDR_HIGH_MASK) >>
  2671. TI_SCI_ADDR_HIGH_SHIFT;
  2672. req->config_flags_set = config_flags_set;
  2673. req->config_flags_clear = config_flags_clear;
  2674. ret = ti_sci_do_xfer(info, xfer);
  2675. if (ret) {
  2676. dev_err(dev, "Mbox send fail %d\n", ret);
  2677. goto fail;
  2678. }
  2679. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  2680. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  2681. fail:
  2682. ti_sci_put_one_xfer(&info->minfo, xfer);
  2683. return ret;
  2684. }
  2685. /**
  2686. * ti_sci_cmd_proc_set_control() - Command to set the processor boot
  2687. * control flags
  2688. * @handle: Pointer to TI SCI handle
  2689. * @proc_id: Processor ID this request is for
  2690. * @control_flags_set: Control flags to be set
  2691. * @control_flags_clear: Control flags to be cleared
  2692. *
  2693. * Return: 0 if all went well, else returns appropriate error value.
  2694. */
  2695. static int ti_sci_cmd_proc_set_control(const struct ti_sci_handle *handle,
  2696. u8 proc_id, u32 control_flags_set,
  2697. u32 control_flags_clear)
  2698. {
  2699. struct ti_sci_msg_req_set_ctrl *req;
  2700. struct ti_sci_msg_hdr *resp;
  2701. struct ti_sci_info *info;
  2702. struct ti_sci_xfer *xfer;
  2703. struct device *dev;
  2704. int ret = 0;
  2705. if (!handle)
  2706. return -EINVAL;
  2707. if (IS_ERR(handle))
  2708. return PTR_ERR(handle);
  2709. info = handle_to_ti_sci_info(handle);
  2710. dev = info->dev;
  2711. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CTRL,
  2712. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2713. sizeof(*req), sizeof(*resp));
  2714. if (IS_ERR(xfer)) {
  2715. ret = PTR_ERR(xfer);
  2716. dev_err(dev, "Message alloc failed(%d)\n", ret);
  2717. return ret;
  2718. }
  2719. req = (struct ti_sci_msg_req_set_ctrl *)xfer->xfer_buf;
  2720. req->processor_id = proc_id;
  2721. req->control_flags_set = control_flags_set;
  2722. req->control_flags_clear = control_flags_clear;
  2723. ret = ti_sci_do_xfer(info, xfer);
  2724. if (ret) {
  2725. dev_err(dev, "Mbox send fail %d\n", ret);
  2726. goto fail;
  2727. }
  2728. resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
  2729. ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
  2730. fail:
  2731. ti_sci_put_one_xfer(&info->minfo, xfer);
  2732. return ret;
  2733. }
  2734. /**
  2735. * ti_sci_cmd_proc_get_status() - Command to get the processor boot status
  2736. * @handle: Pointer to TI SCI handle
  2737. * @proc_id: Processor ID this request is for
  2738. * @bv: Processor Boot vector (start address)
  2739. * @cfg_flags: Processor specific configuration flags
  2740. * @ctrl_flags: Processor specific control flags
  2741. * @sts_flags: Processor specific status flags
  2742. *
  2743. * Return: 0 if all went well, else returns appropriate error value.
  2744. */
  2745. static int ti_sci_cmd_proc_get_status(const struct ti_sci_handle *handle,
  2746. u8 proc_id, u64 *bv, u32 *cfg_flags,
  2747. u32 *ctrl_flags, u32 *sts_flags)
  2748. {
  2749. struct ti_sci_msg_resp_get_status *resp;
  2750. struct ti_sci_msg_req_get_status *req;
  2751. struct ti_sci_info *info;
  2752. struct ti_sci_xfer *xfer;
  2753. struct device *dev;
  2754. int ret = 0;
  2755. if (!handle)
  2756. return -EINVAL;
  2757. if (IS_ERR(handle))
  2758. return PTR_ERR(handle);
  2759. info = handle_to_ti_sci_info(handle);
  2760. dev = info->dev;
  2761. xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_STATUS,
  2762. TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
  2763. sizeof(*req), sizeof(*resp));
  2764. if (IS_ERR(xfer)) {
  2765. ret = PTR_ERR(xfer);
  2766. dev_err(dev, "Message alloc failed(%d)\n", ret);
  2767. return ret;
  2768. }
  2769. req = (struct ti_sci_msg_req_get_status *)xfer->xfer_buf;
  2770. req->processor_id = proc_id;
  2771. ret = ti_sci_do_xfer(info, xfer);
  2772. if (ret) {
  2773. dev_err(dev, "Mbox send fail %d\n", ret);
  2774. goto fail;
  2775. }
  2776. resp = (struct ti_sci_msg_resp_get_status *)xfer->tx_message.buf;
  2777. if (!ti_sci_is_response_ack(resp)) {
  2778. ret = -ENODEV;
  2779. } else {
  2780. *bv = (resp->bootvector_low & TI_SCI_ADDR_LOW_MASK) |
  2781. (((u64)resp->bootvector_high << TI_SCI_ADDR_HIGH_SHIFT) &
  2782. TI_SCI_ADDR_HIGH_MASK);
  2783. *cfg_flags = resp->config_flags;
  2784. *ctrl_flags = resp->control_flags;
  2785. *sts_flags = resp->status_flags;
  2786. }
  2787. fail:
  2788. ti_sci_put_one_xfer(&info->minfo, xfer);
  2789. return ret;
  2790. }
  2791. /*
  2792. * ti_sci_setup_ops() - Setup the operations structures
  2793. * @info: pointer to TISCI pointer
  2794. */
  2795. static void ti_sci_setup_ops(struct ti_sci_info *info)
  2796. {
  2797. struct ti_sci_ops *ops = &info->handle.ops;
  2798. struct ti_sci_core_ops *core_ops = &ops->core_ops;
  2799. struct ti_sci_dev_ops *dops = &ops->dev_ops;
  2800. struct ti_sci_clk_ops *cops = &ops->clk_ops;
  2801. struct ti_sci_pm_ops *pmops = &ops->pm_ops;
  2802. struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
  2803. struct ti_sci_rm_irq_ops *iops = &ops->rm_irq_ops;
  2804. struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops;
  2805. struct ti_sci_rm_psil_ops *psilops = &ops->rm_psil_ops;
  2806. struct ti_sci_rm_udmap_ops *udmap_ops = &ops->rm_udmap_ops;
  2807. struct ti_sci_proc_ops *pops = &ops->proc_ops;
  2808. core_ops->reboot_device = ti_sci_cmd_core_reboot;
  2809. dops->get_device = ti_sci_cmd_get_device;
  2810. dops->get_device_exclusive = ti_sci_cmd_get_device_exclusive;
  2811. dops->idle_device = ti_sci_cmd_idle_device;
  2812. dops->idle_device_exclusive = ti_sci_cmd_idle_device_exclusive;
  2813. dops->put_device = ti_sci_cmd_put_device;
  2814. dops->is_valid = ti_sci_cmd_dev_is_valid;
  2815. dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt;
  2816. dops->is_idle = ti_sci_cmd_dev_is_idle;
  2817. dops->is_stop = ti_sci_cmd_dev_is_stop;
  2818. dops->is_on = ti_sci_cmd_dev_is_on;
  2819. dops->is_transitioning = ti_sci_cmd_dev_is_trans;
  2820. dops->set_device_resets = ti_sci_cmd_set_device_resets;
  2821. dops->get_device_resets = ti_sci_cmd_get_device_resets;
  2822. cops->get_clock = ti_sci_cmd_get_clock;
  2823. cops->idle_clock = ti_sci_cmd_idle_clock;
  2824. cops->put_clock = ti_sci_cmd_put_clock;
  2825. cops->is_auto = ti_sci_cmd_clk_is_auto;
  2826. cops->is_on = ti_sci_cmd_clk_is_on;
  2827. cops->is_off = ti_sci_cmd_clk_is_off;
  2828. cops->set_parent = ti_sci_cmd_clk_set_parent;
  2829. cops->get_parent = ti_sci_cmd_clk_get_parent;
  2830. cops->get_num_parents = ti_sci_cmd_clk_get_num_parents;
  2831. cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
  2832. cops->set_freq = ti_sci_cmd_clk_set_freq;
  2833. cops->get_freq = ti_sci_cmd_clk_get_freq;
  2834. if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
  2835. pr_debug("detected DM managed LPM in fw_caps\n");
  2836. pmops->lpm_wake_reason = ti_sci_msg_cmd_lpm_wake_reason;
  2837. pmops->set_device_constraint = ti_sci_cmd_set_device_constraint;
  2838. pmops->set_latency_constraint = ti_sci_cmd_set_latency_constraint;
  2839. }
  2840. rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
  2841. rm_core_ops->get_range_from_shost =
  2842. ti_sci_cmd_get_resource_range_from_shost;
  2843. iops->set_irq = ti_sci_cmd_set_irq;
  2844. iops->set_event_map = ti_sci_cmd_set_event_map;
  2845. iops->free_irq = ti_sci_cmd_free_irq;
  2846. iops->free_event_map = ti_sci_cmd_free_event_map;
  2847. rops->set_cfg = ti_sci_cmd_rm_ring_cfg;
  2848. psilops->pair = ti_sci_cmd_rm_psil_pair;
  2849. psilops->unpair = ti_sci_cmd_rm_psil_unpair;
  2850. udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg;
  2851. udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg;
  2852. udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg;
  2853. pops->request = ti_sci_cmd_proc_request;
  2854. pops->release = ti_sci_cmd_proc_release;
  2855. pops->handover = ti_sci_cmd_proc_handover;
  2856. pops->set_config = ti_sci_cmd_proc_set_config;
  2857. pops->set_control = ti_sci_cmd_proc_set_control;
  2858. pops->get_status = ti_sci_cmd_proc_get_status;
  2859. }
  2860. /**
  2861. * ti_sci_get_handle() - Get the TI SCI handle for a device
  2862. * @dev: Pointer to device for which we want SCI handle
  2863. *
  2864. * NOTE: The function does not track individual clients of the framework
  2865. * and is expected to be maintained by caller of TI SCI protocol library.
  2866. * ti_sci_put_handle must be balanced with successful ti_sci_get_handle
  2867. * Return: pointer to handle if successful, else:
  2868. * -EPROBE_DEFER if the instance is not ready
  2869. * -ENODEV if the required node handler is missing
  2870. * -EINVAL if invalid conditions are encountered.
  2871. */
  2872. const struct ti_sci_handle *ti_sci_get_handle(struct device *dev)
  2873. {
  2874. struct device_node *ti_sci_np;
  2875. struct ti_sci_handle *handle = NULL;
  2876. struct ti_sci_info *info;
  2877. if (!dev) {
  2878. pr_err("I need a device pointer\n");
  2879. return ERR_PTR(-EINVAL);
  2880. }
  2881. ti_sci_np = of_get_parent(dev->of_node);
  2882. if (!ti_sci_np) {
  2883. dev_err(dev, "No OF information\n");
  2884. return ERR_PTR(-EINVAL);
  2885. }
  2886. mutex_lock(&ti_sci_list_mutex);
  2887. list_for_each_entry(info, &ti_sci_list, node) {
  2888. if (ti_sci_np == info->dev->of_node) {
  2889. handle = &info->handle;
  2890. info->users++;
  2891. break;
  2892. }
  2893. }
  2894. mutex_unlock(&ti_sci_list_mutex);
  2895. of_node_put(ti_sci_np);
  2896. if (!handle)
  2897. return ERR_PTR(-EPROBE_DEFER);
  2898. return handle;
  2899. }
  2900. EXPORT_SYMBOL_GPL(ti_sci_get_handle);
  2901. /**
  2902. * ti_sci_put_handle() - Release the handle acquired by ti_sci_get_handle
  2903. * @handle: Handle acquired by ti_sci_get_handle
  2904. *
  2905. * NOTE: The function does not track individual clients of the framework
  2906. * and is expected to be maintained by caller of TI SCI protocol library.
  2907. * ti_sci_put_handle must be balanced with successful ti_sci_get_handle
  2908. *
  2909. * Return: 0 is successfully released
  2910. * if an error pointer was passed, it returns the error value back,
  2911. * if null was passed, it returns -EINVAL;
  2912. */
  2913. int ti_sci_put_handle(const struct ti_sci_handle *handle)
  2914. {
  2915. struct ti_sci_info *info;
  2916. if (IS_ERR(handle))
  2917. return PTR_ERR(handle);
  2918. if (!handle)
  2919. return -EINVAL;
  2920. info = handle_to_ti_sci_info(handle);
  2921. mutex_lock(&ti_sci_list_mutex);
  2922. if (!WARN_ON(!info->users))
  2923. info->users--;
  2924. mutex_unlock(&ti_sci_list_mutex);
  2925. return 0;
  2926. }
  2927. EXPORT_SYMBOL_GPL(ti_sci_put_handle);
  2928. static void devm_ti_sci_release(struct device *dev, void *res)
  2929. {
  2930. const struct ti_sci_handle **ptr = res;
  2931. const struct ti_sci_handle *handle = *ptr;
  2932. int ret;
  2933. ret = ti_sci_put_handle(handle);
  2934. if (ret)
  2935. dev_err(dev, "failed to put handle %d\n", ret);
  2936. }
  2937. /**
  2938. * devm_ti_sci_get_handle() - Managed get handle
  2939. * @dev: device for which we want SCI handle for.
  2940. *
  2941. * NOTE: This releases the handle once the device resources are
  2942. * no longer needed. MUST NOT BE released with ti_sci_put_handle.
  2943. * The function does not track individual clients of the framework
  2944. * and is expected to be maintained by caller of TI SCI protocol library.
  2945. *
  2946. * Return: 0 if all went fine, else corresponding error.
  2947. */
  2948. const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev)
  2949. {
  2950. const struct ti_sci_handle **ptr;
  2951. const struct ti_sci_handle *handle;
  2952. ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL);
  2953. if (!ptr)
  2954. return ERR_PTR(-ENOMEM);
  2955. handle = ti_sci_get_handle(dev);
  2956. if (!IS_ERR(handle)) {
  2957. *ptr = handle;
  2958. devres_add(dev, ptr);
  2959. } else {
  2960. devres_free(ptr);
  2961. }
  2962. return handle;
  2963. }
  2964. EXPORT_SYMBOL_GPL(devm_ti_sci_get_handle);
  2965. /**
  2966. * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle
  2967. * @np: device node
  2968. * @property: property name containing phandle on TISCI node
  2969. *
  2970. * NOTE: The function does not track individual clients of the framework
  2971. * and is expected to be maintained by caller of TI SCI protocol library.
  2972. * ti_sci_put_handle must be balanced with successful ti_sci_get_by_phandle
  2973. * Return: pointer to handle if successful, else:
  2974. * -EPROBE_DEFER if the instance is not ready
  2975. * -ENODEV if the required node handler is missing
  2976. * -EINVAL if invalid conditions are encountered.
  2977. */
  2978. const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
  2979. const char *property)
  2980. {
  2981. struct ti_sci_handle *handle = NULL;
  2982. struct device_node *ti_sci_np;
  2983. struct ti_sci_info *info;
  2984. if (!np) {
  2985. pr_err("I need a device pointer\n");
  2986. return ERR_PTR(-EINVAL);
  2987. }
  2988. ti_sci_np = of_parse_phandle(np, property, 0);
  2989. if (!ti_sci_np)
  2990. return ERR_PTR(-ENODEV);
  2991. mutex_lock(&ti_sci_list_mutex);
  2992. list_for_each_entry(info, &ti_sci_list, node) {
  2993. if (ti_sci_np == info->dev->of_node) {
  2994. handle = &info->handle;
  2995. info->users++;
  2996. break;
  2997. }
  2998. }
  2999. mutex_unlock(&ti_sci_list_mutex);
  3000. of_node_put(ti_sci_np);
  3001. if (!handle)
  3002. return ERR_PTR(-EPROBE_DEFER);
  3003. return handle;
  3004. }
  3005. EXPORT_SYMBOL_GPL(ti_sci_get_by_phandle);
  3006. /**
  3007. * devm_ti_sci_get_by_phandle() - Managed get handle using phandle
  3008. * @dev: Device pointer requesting TISCI handle
  3009. * @property: property name containing phandle on TISCI node
  3010. *
  3011. * NOTE: This releases the handle once the device resources are
  3012. * no longer needed. MUST NOT BE released with ti_sci_put_handle.
  3013. * The function does not track individual clients of the framework
  3014. * and is expected to be maintained by caller of TI SCI protocol library.
  3015. *
  3016. * Return: 0 if all went fine, else corresponding error.
  3017. */
  3018. const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev,
  3019. const char *property)
  3020. {
  3021. const struct ti_sci_handle *handle;
  3022. const struct ti_sci_handle **ptr;
  3023. ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL);
  3024. if (!ptr)
  3025. return ERR_PTR(-ENOMEM);
  3026. handle = ti_sci_get_by_phandle(dev_of_node(dev), property);
  3027. if (!IS_ERR(handle)) {
  3028. *ptr = handle;
  3029. devres_add(dev, ptr);
  3030. } else {
  3031. devres_free(ptr);
  3032. }
  3033. return handle;
  3034. }
  3035. EXPORT_SYMBOL_GPL(devm_ti_sci_get_by_phandle);
  3036. /**
  3037. * ti_sci_get_free_resource() - Get a free resource from TISCI resource.
  3038. * @res: Pointer to the TISCI resource
  3039. *
  3040. * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL.
  3041. */
  3042. u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
  3043. {
  3044. unsigned long flags;
  3045. u16 set, free_bit;
  3046. raw_spin_lock_irqsave(&res->lock, flags);
  3047. for (set = 0; set < res->sets; set++) {
  3048. struct ti_sci_resource_desc *desc = &res->desc[set];
  3049. int res_count = desc->num + desc->num_sec;
  3050. free_bit = find_first_zero_bit(desc->res_map, res_count);
  3051. if (free_bit != res_count) {
  3052. __set_bit(free_bit, desc->res_map);
  3053. raw_spin_unlock_irqrestore(&res->lock, flags);
  3054. if (desc->num && free_bit < desc->num)
  3055. return desc->start + free_bit;
  3056. else
  3057. return desc->start_sec + free_bit;
  3058. }
  3059. }
  3060. raw_spin_unlock_irqrestore(&res->lock, flags);
  3061. return TI_SCI_RESOURCE_NULL;
  3062. }
  3063. EXPORT_SYMBOL_GPL(ti_sci_get_free_resource);
  3064. /**
  3065. * ti_sci_release_resource() - Release a resource from TISCI resource.
  3066. * @res: Pointer to the TISCI resource
  3067. * @id: Resource id to be released.
  3068. */
  3069. void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
  3070. {
  3071. unsigned long flags;
  3072. u16 set;
  3073. raw_spin_lock_irqsave(&res->lock, flags);
  3074. for (set = 0; set < res->sets; set++) {
  3075. struct ti_sci_resource_desc *desc = &res->desc[set];
  3076. if (desc->num && desc->start <= id &&
  3077. (desc->start + desc->num) > id)
  3078. __clear_bit(id - desc->start, desc->res_map);
  3079. else if (desc->num_sec && desc->start_sec <= id &&
  3080. (desc->start_sec + desc->num_sec) > id)
  3081. __clear_bit(id - desc->start_sec, desc->res_map);
  3082. }
  3083. raw_spin_unlock_irqrestore(&res->lock, flags);
  3084. }
  3085. EXPORT_SYMBOL_GPL(ti_sci_release_resource);
  3086. /**
  3087. * ti_sci_get_num_resources() - Get the number of resources in TISCI resource
  3088. * @res: Pointer to the TISCI resource
  3089. *
  3090. * Return: Total number of available resources.
  3091. */
  3092. u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
  3093. {
  3094. u32 set, count = 0;
  3095. for (set = 0; set < res->sets; set++)
  3096. count += res->desc[set].num + res->desc[set].num_sec;
  3097. return count;
  3098. }
  3099. EXPORT_SYMBOL_GPL(ti_sci_get_num_resources);
  3100. /**
  3101. * devm_ti_sci_get_resource_sets() - Get a TISCI resources assigned to a device
  3102. * @handle: TISCI handle
  3103. * @dev: Device pointer to which the resource is assigned
  3104. * @dev_id: TISCI device id to which the resource is assigned
  3105. * @sub_types: Array of sub_types assigned corresponding to device
  3106. * @sets: Number of sub_types
  3107. *
  3108. * Return: Pointer to ti_sci_resource if all went well else appropriate
  3109. * error pointer.
  3110. */
  3111. static struct ti_sci_resource *
  3112. devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
  3113. struct device *dev, u32 dev_id, u32 *sub_types,
  3114. u32 sets)
  3115. {
  3116. struct ti_sci_resource *res;
  3117. bool valid_set = false;
  3118. int i, ret, res_count;
  3119. res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
  3120. if (!res)
  3121. return ERR_PTR(-ENOMEM);
  3122. res->sets = sets;
  3123. res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
  3124. GFP_KERNEL);
  3125. if (!res->desc)
  3126. return ERR_PTR(-ENOMEM);
  3127. for (i = 0; i < res->sets; i++) {
  3128. ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
  3129. sub_types[i],
  3130. &res->desc[i]);
  3131. if (ret) {
  3132. dev_dbg(dev, "dev = %d subtype %d not allocated for this host\n",
  3133. dev_id, sub_types[i]);
  3134. memset(&res->desc[i], 0, sizeof(res->desc[i]));
  3135. continue;
  3136. }
  3137. dev_dbg(dev, "dev/sub_type: %d/%d, start/num: %d/%d | %d/%d\n",
  3138. dev_id, sub_types[i], res->desc[i].start,
  3139. res->desc[i].num, res->desc[i].start_sec,
  3140. res->desc[i].num_sec);
  3141. valid_set = true;
  3142. res_count = res->desc[i].num + res->desc[i].num_sec;
  3143. res->desc[i].res_map = devm_bitmap_zalloc(dev, res_count,
  3144. GFP_KERNEL);
  3145. if (!res->desc[i].res_map)
  3146. return ERR_PTR(-ENOMEM);
  3147. }
  3148. raw_spin_lock_init(&res->lock);
  3149. if (valid_set)
  3150. return res;
  3151. return ERR_PTR(-EINVAL);
  3152. }
  3153. /**
  3154. * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device
  3155. * @handle: TISCI handle
  3156. * @dev: Device pointer to which the resource is assigned
  3157. * @dev_id: TISCI device id to which the resource is assigned
  3158. * @of_prop: property name by which the resource are represented
  3159. *
  3160. * Return: Pointer to ti_sci_resource if all went well else appropriate
  3161. * error pointer.
  3162. */
  3163. struct ti_sci_resource *
  3164. devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
  3165. struct device *dev, u32 dev_id, char *of_prop)
  3166. {
  3167. struct ti_sci_resource *res;
  3168. u32 *sub_types;
  3169. int sets;
  3170. sets = of_property_count_elems_of_size(dev_of_node(dev), of_prop,
  3171. sizeof(u32));
  3172. if (sets < 0) {
  3173. dev_err(dev, "%s resource type ids not available\n", of_prop);
  3174. return ERR_PTR(sets);
  3175. }
  3176. sub_types = kcalloc(sets, sizeof(*sub_types), GFP_KERNEL);
  3177. if (!sub_types)
  3178. return ERR_PTR(-ENOMEM);
  3179. of_property_read_u32_array(dev_of_node(dev), of_prop, sub_types, sets);
  3180. res = devm_ti_sci_get_resource_sets(handle, dev, dev_id, sub_types,
  3181. sets);
  3182. kfree(sub_types);
  3183. return res;
  3184. }
  3185. EXPORT_SYMBOL_GPL(devm_ti_sci_get_of_resource);
  3186. /**
  3187. * devm_ti_sci_get_resource() - Get a resource range assigned to the device
  3188. * @handle: TISCI handle
  3189. * @dev: Device pointer to which the resource is assigned
  3190. * @dev_id: TISCI device id to which the resource is assigned
  3191. * @sub_type: TISCI resource subytpe representing the resource.
  3192. *
  3193. * Return: Pointer to ti_sci_resource if all went well else appropriate
  3194. * error pointer.
  3195. */
  3196. struct ti_sci_resource *
  3197. devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,
  3198. u32 dev_id, u32 sub_type)
  3199. {
  3200. return devm_ti_sci_get_resource_sets(handle, dev, dev_id, &sub_type, 1);
  3201. }
  3202. EXPORT_SYMBOL_GPL(devm_ti_sci_get_resource);
  3203. /*
  3204. * Iterate all device nodes that have a wakeup-source property and check if one
  3205. * of the possible phandles points to a Partial-IO system state. If it
  3206. * does resolve the device node to an actual device and check if wakeup is
  3207. * enabled.
  3208. */
  3209. static bool ti_sci_partial_io_wakeup_enabled(struct ti_sci_info *info)
  3210. {
  3211. struct device_node *wakeup_node = NULL;
  3212. for_each_node_with_property(wakeup_node, "wakeup-source") {
  3213. struct of_phandle_iterator it;
  3214. int err;
  3215. of_for_each_phandle(&it, err, wakeup_node, "wakeup-source", NULL, 0) {
  3216. struct platform_device *pdev;
  3217. bool may_wakeup;
  3218. /*
  3219. * Continue if idle-state-name is not off-wake. Return
  3220. * value is the index of the string which should be 0 if
  3221. * off-wake is present.
  3222. */
  3223. if (of_property_match_string(it.node, "idle-state-name", "off-wake"))
  3224. continue;
  3225. pdev = of_find_device_by_node(wakeup_node);
  3226. if (!pdev)
  3227. continue;
  3228. may_wakeup = device_may_wakeup(&pdev->dev);
  3229. put_device(&pdev->dev);
  3230. if (may_wakeup) {
  3231. dev_dbg(info->dev, "%pOF identified as wakeup source for Partial-IO\n",
  3232. wakeup_node);
  3233. of_node_put(it.node);
  3234. of_node_put(wakeup_node);
  3235. return true;
  3236. }
  3237. }
  3238. }
  3239. return false;
  3240. }
  3241. static int ti_sci_sys_off_handler(struct sys_off_data *data)
  3242. {
  3243. struct ti_sci_info *info = data->cb_data;
  3244. const struct ti_sci_handle *handle = &info->handle;
  3245. bool enter_partial_io = ti_sci_partial_io_wakeup_enabled(info);
  3246. int ret;
  3247. if (!enter_partial_io)
  3248. return NOTIFY_DONE;
  3249. dev_info(info->dev, "Entering Partial-IO because a powered wakeup-enabled device was found.\n");
  3250. ret = ti_sci_cmd_prepare_sleep(handle, TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO, 0, 0, 0);
  3251. if (ret) {
  3252. dev_err(info->dev,
  3253. "Failed to enter Partial-IO %pe, trying to do an emergency restart\n",
  3254. ERR_PTR(ret));
  3255. emergency_restart();
  3256. }
  3257. mdelay(5000);
  3258. emergency_restart();
  3259. return NOTIFY_DONE;
  3260. }
  3261. static int tisci_reboot_handler(struct sys_off_data *data)
  3262. {
  3263. struct ti_sci_info *info = data->cb_data;
  3264. const struct ti_sci_handle *handle = &info->handle;
  3265. ti_sci_cmd_core_reboot(handle);
  3266. /* call fail OR pass, we should not be here in the first place */
  3267. return NOTIFY_BAD;
  3268. }
  3269. static int ti_sci_prepare_system_suspend(struct ti_sci_info *info)
  3270. {
  3271. /*
  3272. * Map and validate the target Linux suspend state to TISCI LPM.
  3273. * Default is to let Device Manager select the low power mode.
  3274. */
  3275. switch (pm_suspend_target_state) {
  3276. case PM_SUSPEND_MEM:
  3277. if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
  3278. /*
  3279. * For the DM_MANAGED mode the context is reserved for
  3280. * internal use and can be 0
  3281. */
  3282. return ti_sci_cmd_prepare_sleep(&info->handle,
  3283. TISCI_MSG_VALUE_SLEEP_MODE_DM_MANAGED,
  3284. 0, 0, 0);
  3285. } else {
  3286. /* DM Managed is not supported by the firmware. */
  3287. dev_err(info->dev, "Suspend to memory is not supported by the firmware\n");
  3288. return -EOPNOTSUPP;
  3289. }
  3290. break;
  3291. default:
  3292. /*
  3293. * Do not fail if we don't have action to take for a
  3294. * specific suspend mode.
  3295. */
  3296. return 0;
  3297. }
  3298. }
  3299. static int ti_sci_suspend(struct device *dev)
  3300. {
  3301. struct ti_sci_info *info = dev_get_drvdata(dev);
  3302. struct device *cpu_dev, *cpu_dev_max = NULL;
  3303. s32 val, cpu_lat = 0;
  3304. u16 cpu_lat_ms;
  3305. int i, ret;
  3306. if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
  3307. for_each_possible_cpu(i) {
  3308. cpu_dev = get_cpu_device(i);
  3309. val = dev_pm_qos_read_value(cpu_dev, DEV_PM_QOS_RESUME_LATENCY);
  3310. if (val != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) {
  3311. cpu_lat = max(cpu_lat, val);
  3312. cpu_dev_max = cpu_dev;
  3313. }
  3314. }
  3315. if (cpu_dev_max) {
  3316. /*
  3317. * PM QoS latency unit is usecs, device manager uses msecs.
  3318. * Convert to msecs and round down for device manager.
  3319. */
  3320. cpu_lat_ms = cpu_lat / USEC_PER_MSEC;
  3321. dev_dbg(cpu_dev_max, "%s: sending max CPU latency=%u ms\n", __func__,
  3322. cpu_lat_ms);
  3323. ret = ti_sci_cmd_set_latency_constraint(&info->handle,
  3324. cpu_lat_ms,
  3325. TISCI_MSG_CONSTRAINT_SET);
  3326. if (ret)
  3327. return ret;
  3328. }
  3329. }
  3330. ret = ti_sci_prepare_system_suspend(info);
  3331. if (ret)
  3332. return ret;
  3333. return 0;
  3334. }
  3335. static int ti_sci_suspend_noirq(struct device *dev)
  3336. {
  3337. struct ti_sci_info *info = dev_get_drvdata(dev);
  3338. int ret = 0;
  3339. if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) {
  3340. ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_ENABLE);
  3341. if (ret)
  3342. return ret;
  3343. }
  3344. return 0;
  3345. }
  3346. static int ti_sci_resume_noirq(struct device *dev)
  3347. {
  3348. struct ti_sci_info *info = dev_get_drvdata(dev);
  3349. int ret = 0;
  3350. u32 source;
  3351. u64 time;
  3352. u8 pin;
  3353. u8 mode;
  3354. if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) {
  3355. ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE);
  3356. if (ret)
  3357. return ret;
  3358. }
  3359. ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode);
  3360. /* Do not fail to resume on error as the wake reason is not critical */
  3361. if (!ret)
  3362. dev_info(dev, "ti_sci: wakeup source:0x%x, pin:0x%x, mode:0x%x\n",
  3363. source, pin, mode);
  3364. return 0;
  3365. }
  3366. static void ti_sci_pm_complete(struct device *dev)
  3367. {
  3368. struct ti_sci_info *info = dev_get_drvdata(dev);
  3369. if (info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT) {
  3370. if (ti_sci_cmd_lpm_abort(dev))
  3371. dev_err(dev, "LPM clear selection failed.\n");
  3372. }
  3373. }
  3374. static const struct dev_pm_ops ti_sci_pm_ops = {
  3375. .suspend = pm_sleep_ptr(ti_sci_suspend),
  3376. .suspend_noirq = pm_sleep_ptr(ti_sci_suspend_noirq),
  3377. .resume_noirq = pm_sleep_ptr(ti_sci_resume_noirq),
  3378. .complete = pm_sleep_ptr(ti_sci_pm_complete),
  3379. };
  3380. /* Description for K2G */
  3381. static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
  3382. .default_host_id = 2,
  3383. /* Conservative duration */
  3384. .max_rx_timeout_ms = 1000,
  3385. /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
  3386. .max_msgs = 20,
  3387. .max_msg_size = 64,
  3388. };
  3389. /* Description for AM654 */
  3390. static const struct ti_sci_desc ti_sci_pmmc_am654_desc = {
  3391. .default_host_id = 12,
  3392. /* Conservative duration */
  3393. .max_rx_timeout_ms = 10000,
  3394. /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
  3395. .max_msgs = 20,
  3396. .max_msg_size = 60,
  3397. };
  3398. static const struct of_device_id ti_sci_of_match[] = {
  3399. {.compatible = "ti,k2g-sci", .data = &ti_sci_pmmc_k2g_desc},
  3400. {.compatible = "ti,am654-sci", .data = &ti_sci_pmmc_am654_desc},
  3401. { /* Sentinel */ },
  3402. };
  3403. MODULE_DEVICE_TABLE(of, ti_sci_of_match);
  3404. static int ti_sci_probe(struct platform_device *pdev)
  3405. {
  3406. struct device *dev = &pdev->dev;
  3407. const struct ti_sci_desc *desc;
  3408. struct ti_sci_xfer *xfer;
  3409. struct ti_sci_info *info = NULL;
  3410. struct ti_sci_xfers_info *minfo;
  3411. struct mbox_client *cl;
  3412. int ret = -EINVAL;
  3413. int i;
  3414. u32 h_id;
  3415. desc = device_get_match_data(dev);
  3416. info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
  3417. if (!info)
  3418. return -ENOMEM;
  3419. info->dev = dev;
  3420. info->desc = desc;
  3421. ret = of_property_read_u32(dev->of_node, "ti,host-id", &h_id);
  3422. /* if the property is not present in DT, use a default from desc */
  3423. if (ret < 0) {
  3424. info->host_id = info->desc->default_host_id;
  3425. } else {
  3426. if (!h_id) {
  3427. dev_warn(dev, "Host ID 0 is reserved for firmware\n");
  3428. info->host_id = info->desc->default_host_id;
  3429. } else {
  3430. info->host_id = h_id;
  3431. }
  3432. }
  3433. INIT_LIST_HEAD(&info->node);
  3434. minfo = &info->minfo;
  3435. /*
  3436. * Pre-allocate messages
  3437. * NEVER allocate more than what we can indicate in hdr.seq
  3438. * if we have data description bug, force a fix..
  3439. */
  3440. if (WARN_ON(desc->max_msgs >=
  3441. 1 << 8 * sizeof(((struct ti_sci_msg_hdr *)0)->seq)))
  3442. return -EINVAL;
  3443. minfo->xfer_block = devm_kcalloc(dev,
  3444. desc->max_msgs,
  3445. sizeof(*minfo->xfer_block),
  3446. GFP_KERNEL);
  3447. if (!minfo->xfer_block)
  3448. return -ENOMEM;
  3449. minfo->xfer_alloc_table = devm_bitmap_zalloc(dev,
  3450. desc->max_msgs,
  3451. GFP_KERNEL);
  3452. if (!minfo->xfer_alloc_table)
  3453. return -ENOMEM;
  3454. /* Pre-initialize the buffer pointer to pre-allocated buffers */
  3455. for (i = 0, xfer = minfo->xfer_block; i < desc->max_msgs; i++, xfer++) {
  3456. xfer->xfer_buf = devm_kcalloc(dev, 1, desc->max_msg_size,
  3457. GFP_KERNEL);
  3458. if (!xfer->xfer_buf)
  3459. return -ENOMEM;
  3460. xfer->tx_message.buf = xfer->xfer_buf;
  3461. init_completion(&xfer->done);
  3462. }
  3463. ret = ti_sci_debugfs_create(pdev, info);
  3464. if (ret)
  3465. dev_warn(dev, "Failed to create debug file\n");
  3466. platform_set_drvdata(pdev, info);
  3467. cl = &info->cl;
  3468. cl->dev = dev;
  3469. cl->tx_block = false;
  3470. cl->rx_callback = ti_sci_rx_callback;
  3471. cl->knows_txdone = true;
  3472. spin_lock_init(&minfo->xfer_lock);
  3473. sema_init(&minfo->sem_xfer_count, desc->max_msgs);
  3474. info->chan_rx = mbox_request_channel_byname(cl, "rx");
  3475. if (IS_ERR(info->chan_rx)) {
  3476. ret = PTR_ERR(info->chan_rx);
  3477. goto out;
  3478. }
  3479. info->chan_tx = mbox_request_channel_byname(cl, "tx");
  3480. if (IS_ERR(info->chan_tx)) {
  3481. ret = PTR_ERR(info->chan_tx);
  3482. goto out;
  3483. }
  3484. ret = ti_sci_cmd_get_revision(info);
  3485. if (ret) {
  3486. dev_err(dev, "Unable to communicate with TISCI(%d)\n", ret);
  3487. goto out;
  3488. }
  3489. ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps);
  3490. dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s\n",
  3491. info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "",
  3492. info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "",
  3493. info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "",
  3494. info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "",
  3495. info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : ""
  3496. );
  3497. ti_sci_setup_ops(info);
  3498. ret = devm_register_restart_handler(dev, tisci_reboot_handler, info);
  3499. if (ret) {
  3500. dev_err(dev, "reboot registration fail(%d)\n", ret);
  3501. goto out;
  3502. }
  3503. if (info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO) {
  3504. ret = devm_register_sys_off_handler(dev,
  3505. SYS_OFF_MODE_POWER_OFF,
  3506. SYS_OFF_PRIO_FIRMWARE,
  3507. ti_sci_sys_off_handler,
  3508. info);
  3509. if (ret) {
  3510. dev_err(dev, "Failed to register sys_off_handler %pe\n",
  3511. ERR_PTR(ret));
  3512. goto out;
  3513. }
  3514. }
  3515. dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n",
  3516. info->handle.version.abi_major, info->handle.version.abi_minor,
  3517. info->handle.version.firmware_revision,
  3518. info->handle.version.firmware_description);
  3519. mutex_lock(&ti_sci_list_mutex);
  3520. list_add_tail(&info->node, &ti_sci_list);
  3521. mutex_unlock(&ti_sci_list_mutex);
  3522. ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
  3523. if (ret) {
  3524. dev_err(dev, "platform_populate failed %pe\n", ERR_PTR(ret));
  3525. goto out;
  3526. }
  3527. return 0;
  3528. out:
  3529. if (!IS_ERR(info->chan_tx))
  3530. mbox_free_channel(info->chan_tx);
  3531. if (!IS_ERR(info->chan_rx))
  3532. mbox_free_channel(info->chan_rx);
  3533. debugfs_remove(info->d);
  3534. return ret;
  3535. }
  3536. static struct platform_driver ti_sci_driver = {
  3537. .probe = ti_sci_probe,
  3538. .driver = {
  3539. .name = "ti-sci",
  3540. .of_match_table = ti_sci_of_match,
  3541. .suppress_bind_attrs = true,
  3542. .pm = &ti_sci_pm_ops,
  3543. },
  3544. };
  3545. module_platform_driver(ti_sci_driver);
  3546. MODULE_LICENSE("GPL v2");
  3547. MODULE_DESCRIPTION("TI System Control Interface(SCI) driver");
  3548. MODULE_AUTHOR("Nishanth Menon");
  3549. MODULE_ALIAS("platform:ti-sci");