dwc_otg_hcd.c 93 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406
  1. /* ==========================================================================
  2. * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.c $
  3. * $Revision: #104 $
  4. * $Date: 2011/10/24 $
  5. * $Change: 1871159 $
  6. *
  7. * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  8. * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  9. * otherwise expressly agreed to in writing between Synopsys and you.
  10. *
  11. * The Software IS NOT an item of Licensed Software or Licensed Product under
  12. * any End User Software License Agreement or Agreement for Licensed Product
  13. * with Synopsys or any supplement thereto. You are permitted to use and
  14. * redistribute this Software in source and binary forms, with or without
  15. * modification, provided that redistributions of source code must retain this
  16. * notice. You may not view, use, disclose, copy or distribute this file or
  17. * any information contained herein except pursuant to this license grant from
  18. * Synopsys. If you do not agree with this notice, including the disclaimer
  19. * below, then you are not authorized to use the Software.
  20. *
  21. * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  22. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  25. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  27. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  28. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  31. * DAMAGE.
  32. * ========================================================================== */
  33. #ifndef DWC_DEVICE_ONLY
  34. /** @file
  35. * This file implements HCD Core. All code in this file is portable and doesn't
  36. * use any OS specific functions.
  37. * Interface provided by HCD Core is defined in <code><hcd_if.h></code>
  38. * header file.
  39. */
  40. #include "dwc_otg_hcd.h"
  41. #include "dwc_otg_regs.h"
  42. dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void)
  43. {
  44. return DWC_ALLOC(sizeof(dwc_otg_hcd_t));
  45. }
  46. /**
  47. * Connection timeout function. An OTG host is required to display a
  48. * message if the device does not connect within 10 seconds.
  49. */
  50. void dwc_otg_hcd_connect_timeout(void *ptr)
  51. {
  52. DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, ptr);
  53. DWC_PRINTF("Connect Timeout\n");
  54. __DWC_ERROR("Device Not Connected/Responding\n");
  55. }
  56. #ifdef DEBUG
  57. static void dump_channel_info(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
  58. {
  59. if (qh->channel != NULL) {
  60. dwc_hc_t *hc = qh->channel;
  61. dwc_list_link_t *item;
  62. dwc_otg_qh_t *qh_item;
  63. int num_channels = hcd->core_if->core_params->host_channels;
  64. int i;
  65. dwc_otg_hc_regs_t *hc_regs;
  66. hcchar_data_t hcchar;
  67. hcsplt_data_t hcsplt;
  68. hctsiz_data_t hctsiz;
  69. uint32_t hcdma;
  70. hc_regs = hcd->core_if->host_if->hc_regs[hc->hc_num];
  71. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  72. hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
  73. hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
  74. hcdma = DWC_READ_REG32(&hc_regs->hcdma);
  75. DWC_PRINTF(" Assigned to channel %p:\n", hc);
  76. DWC_PRINTF(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32,
  77. hcsplt.d32);
  78. DWC_PRINTF(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32,
  79. hcdma);
  80. DWC_PRINTF(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
  81. hc->dev_addr, hc->ep_num, hc->ep_is_in);
  82. DWC_PRINTF(" ep_type: %d\n", hc->ep_type);
  83. DWC_PRINTF(" max_packet: %d\n", hc->max_packet);
  84. DWC_PRINTF(" data_pid_start: %d\n", hc->data_pid_start);
  85. DWC_PRINTF(" xfer_started: %d\n", hc->xfer_started);
  86. DWC_PRINTF(" halt_status: %d\n", hc->halt_status);
  87. DWC_PRINTF(" xfer_buff: %p\n", hc->xfer_buff);
  88. DWC_PRINTF(" xfer_len: %d\n", hc->xfer_len);
  89. DWC_PRINTF(" qh: %p\n", hc->qh);
  90. DWC_PRINTF(" NP inactive sched:\n");
  91. DWC_LIST_FOREACH(item, &hcd->non_periodic_sched_inactive) {
  92. qh_item =
  93. DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry);
  94. DWC_PRINTF(" %p\n", qh_item);
  95. }
  96. DWC_PRINTF(" NP active sched:\n");
  97. DWC_LIST_FOREACH(item, &hcd->non_periodic_sched_active) {
  98. qh_item =
  99. DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry);
  100. DWC_PRINTF(" %p\n", qh_item);
  101. }
  102. DWC_PRINTF(" Channels: \n");
  103. for (i = 0; i < num_channels; i++) {
  104. dwc_hc_t *hc = hcd->hc_ptr_array[i];
  105. DWC_PRINTF(" %2d: %p\n", i, hc);
  106. }
  107. }
  108. }
  109. #endif /* DEBUG */
  110. /**
  111. * Work queue function for starting the HCD when A-Cable is connected.
  112. * The hcd_start() must be called in a process context.
  113. */
  114. static void hcd_start_func(void *_vp)
  115. {
  116. dwc_otg_hcd_t *hcd = (dwc_otg_hcd_t *) _vp;
  117. DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, hcd);
  118. if (hcd) {
  119. hcd->fops->start(hcd);
  120. }
  121. }
  122. static void del_xfer_timers(dwc_otg_hcd_t * hcd)
  123. {
  124. #ifdef DEBUG
  125. int i;
  126. int num_channels = hcd->core_if->core_params->host_channels;
  127. for (i = 0; i < num_channels; i++) {
  128. DWC_TIMER_CANCEL(hcd->core_if->hc_xfer_timer[i]);
  129. }
  130. #endif
  131. }
  132. static void del_timers(dwc_otg_hcd_t * hcd)
  133. {
  134. del_xfer_timers(hcd);
  135. DWC_TIMER_CANCEL(hcd->conn_timer);
  136. }
  137. /**
  138. * Processes all the URBs in a single list of QHs. Completes them with
  139. * -ETIMEDOUT and frees the QTD.
  140. */
  141. static void kill_urbs_in_qh_list(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list)
  142. {
  143. dwc_list_link_t *qh_item;
  144. dwc_otg_qh_t *qh;
  145. dwc_otg_qtd_t *qtd, *qtd_tmp;
  146. DWC_LIST_FOREACH(qh_item, qh_list) {
  147. qh = DWC_LIST_ENTRY(qh_item, dwc_otg_qh_t, qh_list_entry);
  148. DWC_CIRCLEQ_FOREACH_SAFE(qtd, qtd_tmp,
  149. &qh->qtd_list, qtd_list_entry) {
  150. qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
  151. if (qtd->urb != NULL) {
  152. hcd->fops->complete(hcd, qtd->urb->priv,
  153. qtd->urb, -DWC_E_TIMEOUT);
  154. dwc_otg_hcd_qtd_remove_and_free(hcd, qtd, qh);
  155. }
  156. }
  157. }
  158. }
  159. /**
  160. * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
  161. * and periodic schedules. The QTD associated with each URB is removed from
  162. * the schedule and freed. This function may be called when a disconnect is
  163. * detected or when the HCD is being stopped.
  164. */
  165. static void kill_all_urbs(dwc_otg_hcd_t * hcd)
  166. {
  167. kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_inactive);
  168. kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_active);
  169. kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_inactive);
  170. kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_ready);
  171. kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_assigned);
  172. kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_queued);
  173. }
  174. /**
  175. * Start the connection timer. An OTG host is required to display a
  176. * message if the device does not connect within 10 seconds. The
  177. * timer is deleted if a port connect interrupt occurs before the
  178. * timer expires.
  179. */
  180. static void dwc_otg_hcd_start_connect_timer(dwc_otg_hcd_t * hcd)
  181. {
  182. DWC_TIMER_SCHEDULE(hcd->conn_timer, 10000 /* 10 secs */ );
  183. }
  184. /**
  185. * HCD Callback function for disconnect of the HCD.
  186. *
  187. * @param p void pointer to the <code>struct usb_hcd</code>
  188. */
  189. static int32_t dwc_otg_hcd_session_start_cb(void *p)
  190. {
  191. dwc_otg_hcd_t *dwc_otg_hcd;
  192. DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
  193. dwc_otg_hcd = p;
  194. dwc_otg_hcd_start_connect_timer(dwc_otg_hcd);
  195. return 1;
  196. }
  197. /**
  198. * HCD Callback function for starting the HCD when A-Cable is
  199. * connected.
  200. *
  201. * @param p void pointer to the <code>struct usb_hcd</code>
  202. */
  203. static int32_t dwc_otg_hcd_start_cb(void *p)
  204. {
  205. dwc_otg_hcd_t *dwc_otg_hcd = p;
  206. dwc_otg_core_if_t *core_if;
  207. hprt0_data_t hprt0;
  208. core_if = dwc_otg_hcd->core_if;
  209. if (core_if->op_state == B_HOST) {
  210. /*
  211. * Reset the port. During a HNP mode switch the reset
  212. * needs to occur within 1ms and have a duration of at
  213. * least 50ms.
  214. */
  215. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  216. hprt0.b.prtrst = 1;
  217. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  218. }
  219. DWC_WORKQ_SCHEDULE_DELAYED(core_if->wq_otg,
  220. hcd_start_func, dwc_otg_hcd, 50,
  221. "start hcd");
  222. return 1;
  223. }
  224. /**
  225. * HCD Callback function for disconnect of the HCD.
  226. *
  227. * @param p void pointer to the <code>struct usb_hcd</code>
  228. */
  229. static int32_t dwc_otg_hcd_disconnect_cb(void *p)
  230. {
  231. gintsts_data_t intr;
  232. dwc_otg_hcd_t *dwc_otg_hcd = p;
  233. /*
  234. * Set status flags for the hub driver.
  235. */
  236. dwc_otg_hcd->flags.b.port_connect_status_change = 1;
  237. dwc_otg_hcd->flags.b.port_connect_status = 0;
  238. /*
  239. * Shutdown any transfers in process by clearing the Tx FIFO Empty
  240. * interrupt mask and status bits and disabling subsequent host
  241. * channel interrupts.
  242. */
  243. intr.d32 = 0;
  244. intr.b.nptxfempty = 1;
  245. intr.b.ptxfempty = 1;
  246. intr.b.hcintr = 1;
  247. DWC_MODIFY_REG32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk,
  248. intr.d32, 0);
  249. DWC_MODIFY_REG32(&dwc_otg_hcd->core_if->core_global_regs->gintsts,
  250. intr.d32, 0);
  251. del_timers(dwc_otg_hcd);
  252. /*
  253. * Turn off the vbus power only if the core has transitioned to device
  254. * mode. If still in host mode, need to keep power on to detect a
  255. * reconnection.
  256. */
  257. if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) {
  258. if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) {
  259. hprt0_data_t hprt0 = {.d32 = 0 };
  260. DWC_PRINTF("Disconnect: PortPower off\n");
  261. hprt0.b.prtpwr = 0;
  262. DWC_WRITE_REG32(dwc_otg_hcd->core_if->host_if->hprt0,
  263. hprt0.d32);
  264. dwc_otg_set_vbus_power(dwc_otg_hcd->core_if, 0); //Power off VBus
  265. }
  266. dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if);
  267. }
  268. /* Respond with an error status to all URBs in the schedule. */
  269. kill_all_urbs(dwc_otg_hcd);
  270. if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
  271. /* Clean up any host channels that were in use. */
  272. int num_channels;
  273. int i;
  274. dwc_hc_t *channel;
  275. dwc_otg_hc_regs_t *hc_regs;
  276. hcchar_data_t hcchar;
  277. num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
  278. if (!dwc_otg_hcd->core_if->dma_enable) {
  279. /* Flush out any channel requests in slave mode. */
  280. for (i = 0; i < num_channels; i++) {
  281. channel = dwc_otg_hcd->hc_ptr_array[i];
  282. if (DWC_CIRCLEQ_EMPTY_ENTRY
  283. (channel, hc_list_entry)) {
  284. hc_regs =
  285. dwc_otg_hcd->core_if->
  286. host_if->hc_regs[i];
  287. hcchar.d32 =
  288. DWC_READ_REG32(&hc_regs->hcchar);
  289. if (hcchar.b.chen) {
  290. hcchar.b.chen = 0;
  291. hcchar.b.chdis = 1;
  292. hcchar.b.epdir = 0;
  293. DWC_WRITE_REG32
  294. (&hc_regs->hcchar,
  295. hcchar.d32);
  296. }
  297. }
  298. }
  299. }
  300. for (i = 0; i < num_channels; i++) {
  301. channel = dwc_otg_hcd->hc_ptr_array[i];
  302. if (DWC_CIRCLEQ_EMPTY_ENTRY(channel, hc_list_entry)) {
  303. hc_regs =
  304. dwc_otg_hcd->core_if->host_if->hc_regs[i];
  305. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  306. if (hcchar.b.chen) {
  307. /* Halt the channel. */
  308. hcchar.b.chdis = 1;
  309. DWC_WRITE_REG32(&hc_regs->hcchar,
  310. hcchar.d32);
  311. }
  312. dwc_otg_hc_cleanup(dwc_otg_hcd->core_if,
  313. channel);
  314. DWC_CIRCLEQ_INSERT_TAIL
  315. (&dwc_otg_hcd->free_hc_list, channel,
  316. hc_list_entry);
  317. /* Take back a non_periodic_channel */
  318. switch (channel->ep_type) {
  319. case DWC_OTG_EP_TYPE_CONTROL:
  320. case DWC_OTG_EP_TYPE_BULK:
  321. dwc_otg_hcd->non_periodic_channels--;
  322. break;
  323. default:
  324. break;
  325. }
  326. /*
  327. * Added for Descriptor DMA to prevent channel double cleanup
  328. * in release_channel_ddma(). Which called from ep_disable
  329. * when device disconnect.
  330. */
  331. channel->qh = NULL;
  332. }
  333. }
  334. }
  335. if (dwc_otg_hcd->fops->disconnect) {
  336. dwc_otg_hcd->fops->disconnect(dwc_otg_hcd);
  337. }
  338. return 1;
  339. }
  340. /**
  341. * HCD Callback function for stopping the HCD.
  342. *
  343. * @param p void pointer to the <code>struct usb_hcd</code>
  344. */
  345. static int32_t dwc_otg_hcd_stop_cb(void *p)
  346. {
  347. dwc_otg_hcd_t *dwc_otg_hcd = p;
  348. DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, p);
  349. dwc_otg_hcd_stop(dwc_otg_hcd);
  350. return 1;
  351. }
  352. #ifdef CONFIG_USB_DWC_OTG_LPM
  353. /**
  354. * HCD Callback function for sleep of HCD.
  355. *
  356. * @param p void pointer to the <code>struct usb_hcd</code>
  357. */
  358. static int dwc_otg_hcd_sleep_cb(void *p)
  359. {
  360. dwc_otg_hcd_t *hcd = p;
  361. dwc_otg_hcd_free_hc_from_lpm(hcd);
  362. return 0;
  363. }
  364. #endif
  365. /**
  366. * HCD Callback function for Remote Wakeup.
  367. *
  368. * @param p void pointer to the <code>struct usb_hcd</code>
  369. */
  370. static int dwc_otg_hcd_rem_wakeup_cb(void *p)
  371. {
  372. dwc_otg_hcd_t *hcd = p;
  373. if (hcd->core_if->lx_state == DWC_OTG_L2) {
  374. hcd->flags.b.port_suspend_change = 1;
  375. }
  376. #ifdef CONFIG_USB_DWC_OTG_LPM
  377. else {
  378. hcd->flags.b.port_l1_change = 1;
  379. }
  380. #endif
  381. return 0;
  382. }
  383. /**
  384. * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
  385. * stopped.
  386. */
  387. void dwc_otg_hcd_stop(dwc_otg_hcd_t * hcd)
  388. {
  389. hprt0_data_t hprt0 = {.d32 = 0 };
  390. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
  391. /*
  392. * The root hub should be disconnected before this function is called.
  393. * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
  394. * and the QH lists (via ..._hcd_endpoint_disable).
  395. */
  396. /* Turn off all host-specific interrupts. */
  397. dwc_otg_disable_host_interrupts(hcd->core_if);
  398. /* Turn off the vbus power */
  399. DWC_PRINTF("PortPower off\n");
  400. hprt0.b.prtpwr = 0;
  401. DWC_WRITE_REG32(hcd->core_if->host_if->hprt0, hprt0.d32);
  402. /* control the GPIO the power off VBUS */
  403. dwc_otg_set_vbus_power(hcd->core_if, 0);
  404. dwc_mdelay(1);
  405. }
  406. /** dwc_otg_hcd suspend */
  407. int dwc_otg_hcd_suspend(dwc_otg_hcd_t * hcd)
  408. {
  409. usb_dbg_uart_data_t uart = {.d32 = 0 };
  410. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD SUSPEND\n");
  411. uart.d32 = DWC_READ_REG32(&hcd->core_if->usb_peri_reg->dbg_uart);
  412. uart.b.set_iddq = 1;
  413. DWC_WRITE_REG32(&hcd->core_if->usb_peri_reg->dbg_uart,uart.d32);
  414. return 0;
  415. }
  416. /** dwc_otg_hcd resume */
  417. int dwc_otg_hcd_resume(dwc_otg_hcd_t *hcd)
  418. {
  419. usb_dbg_uart_data_t uart = {.d32 = 0 };
  420. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD SUSPEND\n");
  421. uart.d32 = DWC_READ_REG32(&hcd->core_if->usb_peri_reg->dbg_uart);
  422. uart.b.set_iddq = 0;
  423. DWC_WRITE_REG32(&hcd->core_if->usb_peri_reg->dbg_uart,uart.d32);
  424. return 0;
  425. }
  426. int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_t * hcd,
  427. dwc_otg_hcd_urb_t * dwc_otg_urb, void **ep_handle,
  428. int atomic_alloc)
  429. {
  430. dwc_irqflags_t flags;
  431. int retval = 0;
  432. int bulk_not_asap = 0;
  433. dwc_otg_qtd_t *qtd;
  434. gintmsk_data_t intr_mask = {.d32 = 0 };
  435. if (!hcd->flags.b.port_connect_status) {
  436. /* No longer connected. */
  437. DWC_ERROR("Not connected\n");
  438. return -DWC_E_NO_DEVICE;
  439. }
  440. if((dwc_otg_urb->pipe_info.pipe_type == UE_BULK)
  441. && !(dwc_otg_urb->flags & URB_GIVEBACK_ASAP))
  442. bulk_not_asap = 1;
  443. qtd = dwc_otg_hcd_qtd_create(dwc_otg_urb, atomic_alloc);
  444. if (qtd == NULL) {
  445. DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
  446. retval = -DWC_E_NO_MEMORY;
  447. goto OUT;
  448. }
  449. retval =
  450. dwc_otg_hcd_qtd_add(qtd, hcd, (dwc_otg_qh_t **) ep_handle, atomic_alloc);
  451. if (retval < 0) {
  452. DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
  453. "Error status %d\n", retval);
  454. dwc_otg_hcd_qtd_free(qtd);
  455. }
  456. intr_mask.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->gintmsk);
  457. if (!intr_mask.b.sofintr && retval == 0) {
  458. dwc_otg_transaction_type_e tr_type;
  459. if (bulk_not_asap) {
  460. /* Do not schedule SG transcations until qtd has URB_GIVEBACK_ASAP set */
  461. retval = 0;
  462. goto OUT;
  463. }
  464. DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
  465. tr_type = dwc_otg_hcd_select_transactions(hcd);
  466. if (tr_type != DWC_OTG_TRANSACTION_NONE) {
  467. dwc_otg_hcd_queue_transactions(hcd, tr_type);
  468. }
  469. DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
  470. }
  471. OUT:
  472. return retval;
  473. }
  474. int dwc_otg_hcd_urb_dequeue(dwc_otg_hcd_t * hcd,
  475. dwc_otg_hcd_urb_t * dwc_otg_urb)
  476. {
  477. dwc_otg_qh_t *qh;
  478. dwc_otg_qtd_t *urb_qtd;
  479. urb_qtd = dwc_otg_urb->qtd;
  480. if(urb_qtd && urb_qtd->qh)
  481. qh = urb_qtd->qh;
  482. else{
  483. DWC_ERROR("DWC OTG HCD URB Dequeue.NO QTD\n");
  484. return 0;
  485. }
  486. #ifdef DEBUG
  487. if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
  488. if (urb_qtd->in_process) {
  489. dump_channel_info(hcd, qh);
  490. }
  491. }
  492. #endif
  493. if (urb_qtd->in_process && qh->channel) {
  494. /* The QTD is in process (it has been assigned to a channel). */
  495. if (hcd->flags.b.port_connect_status) {
  496. /*
  497. * If still connected (i.e. in host mode), halt the
  498. * channel so it can be used for other transfers. If
  499. * no longer connected, the host registers can't be
  500. * written to halt the channel since the core is in
  501. * device mode.
  502. */
  503. dwc_otg_hc_halt(hcd->core_if, qh->channel,
  504. DWC_OTG_HC_XFER_URB_DEQUEUE);
  505. }
  506. }
  507. /*
  508. * Free the QTD and clean up the associated QH. Leave the QH in the
  509. * schedule if it has any remaining QTDs.
  510. */
  511. if (!hcd->core_if->dma_desc_enable) {
  512. uint8_t b = urb_qtd->in_process;
  513. dwc_otg_hcd_qtd_remove_and_free(hcd, urb_qtd, qh);
  514. if (b) {
  515. dwc_otg_hcd_qh_deactivate(hcd, qh, 0);
  516. qh->channel = NULL;
  517. } else if (DWC_CIRCLEQ_EMPTY(&qh->qtd_list)) {
  518. dwc_otg_hcd_qh_remove(hcd, qh);
  519. }
  520. } else {
  521. dwc_otg_hcd_qtd_remove_and_free(hcd, urb_qtd, qh);
  522. }
  523. return 0;
  524. }
  525. int dwc_otg_hcd_endpoint_disable(dwc_otg_hcd_t * hcd, void *ep_handle,
  526. int retry)
  527. {
  528. dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
  529. int retval = 0;
  530. dwc_irqflags_t flags;
  531. if (retry < 0) {
  532. retval = -DWC_E_INVALID;
  533. goto done;
  534. }
  535. if (!qh) {
  536. retval = -DWC_E_INVALID;
  537. goto done;
  538. }
  539. DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
  540. while (!DWC_CIRCLEQ_EMPTY(&qh->qtd_list) && retry) {
  541. DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
  542. retry--;
  543. dwc_msleep(5);
  544. DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
  545. }
  546. dwc_otg_hcd_qh_remove(hcd, qh);
  547. DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
  548. /*
  549. * Split dwc_otg_hcd_qh_remove_and_free() into qh_remove
  550. * and qh_free to prevent stack dump on DWC_DMA_FREE() with
  551. * irq_disabled (spinlock_irqsave) in dwc_otg_hcd_desc_list_free()
  552. * and dwc_otg_hcd_frame_list_alloc().
  553. */
  554. dwc_otg_hcd_qh_free(hcd, qh);
  555. done:
  556. return retval;
  557. }
  558. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
  559. int dwc_otg_hcd_endpoint_reset(dwc_otg_hcd_t * hcd, void *ep_handle)
  560. {
  561. int retval = 0;
  562. dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
  563. if (!qh)
  564. return -DWC_E_INVALID;
  565. qh->data_toggle = DWC_OTG_HC_PID_DATA0;
  566. return retval;
  567. }
  568. #endif
  569. /**
  570. * HCD Callback structure for handling mode switching.
  571. */
  572. static dwc_otg_cil_callbacks_t hcd_cil_callbacks = {
  573. .start = dwc_otg_hcd_start_cb,
  574. .stop = dwc_otg_hcd_stop_cb,
  575. .disconnect = dwc_otg_hcd_disconnect_cb,
  576. .session_start = dwc_otg_hcd_session_start_cb,
  577. .resume_wakeup = dwc_otg_hcd_rem_wakeup_cb,
  578. #ifdef CONFIG_USB_DWC_OTG_LPM
  579. .sleep = dwc_otg_hcd_sleep_cb,
  580. #endif
  581. };
  582. /**
  583. * Reset tasklet function
  584. */
  585. static void reset_tasklet_func(void *data)
  586. {
  587. dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *) data;
  588. dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
  589. hprt0_data_t hprt0;
  590. DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
  591. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  592. hprt0.b.prtrst = 1;
  593. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  594. dwc_mdelay(60);
  595. hprt0.b.prtrst = 0;
  596. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  597. dwc_otg_hcd->flags.b.port_reset_change = 1;
  598. }
  599. static void qh_list_free(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list)
  600. {
  601. dwc_list_link_t *item;
  602. dwc_otg_qh_t *qh;
  603. dwc_irqflags_t flags;
  604. if (!qh_list->next) {
  605. /* The list hasn't been initialized yet. */
  606. return;
  607. }
  608. /*
  609. * Hold spinlock here. Not needed in that case if bellow
  610. * function is being called from ISR
  611. */
  612. DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
  613. /* Ensure there are no QTDs or URBs left. */
  614. kill_urbs_in_qh_list(hcd, qh_list);
  615. DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
  616. DWC_LIST_FOREACH(item, qh_list) {
  617. qh = DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry);
  618. dwc_otg_hcd_qh_remove_and_free(hcd, qh);
  619. }
  620. }
  621. /**
  622. * Exit from Hibernation if Host did not detect SRP from connected SRP capable
  623. * Device during SRP time by host power up.
  624. */
  625. void dwc_otg_hcd_power_up(void *ptr)
  626. {
  627. gpwrdn_data_t gpwrdn = {.d32 = 0 };
  628. dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) ptr;
  629. DWC_PRINTF("%s called\n", __FUNCTION__);
  630. if (!core_if->hibernation_suspend) {
  631. DWC_PRINTF("Already exited from Hibernation\n");
  632. return;
  633. }
  634. /* Switch on the voltage to the core */
  635. gpwrdn.b.pwrdnswtch = 1;
  636. DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
  637. dwc_udelay(10);
  638. /* Reset the core */
  639. gpwrdn.d32 = 0;
  640. gpwrdn.b.pwrdnrstn = 1;
  641. DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
  642. dwc_udelay(10);
  643. /* Disable power clamps */
  644. gpwrdn.d32 = 0;
  645. gpwrdn.b.pwrdnclmp = 1;
  646. DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
  647. /* Remove reset the core signal */
  648. gpwrdn.d32 = 0;
  649. gpwrdn.b.pwrdnrstn = 1;
  650. DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
  651. dwc_udelay(10);
  652. /* Disable PMU interrupt */
  653. gpwrdn.d32 = 0;
  654. gpwrdn.b.pmuintsel = 1;
  655. DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
  656. core_if->hibernation_suspend = 0;
  657. /* Disable PMU */
  658. gpwrdn.d32 = 0;
  659. gpwrdn.b.pmuactv = 1;
  660. DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
  661. dwc_udelay(10);
  662. /* Enable VBUS */
  663. gpwrdn.d32 = 0;
  664. gpwrdn.b.dis_vbus = 1;
  665. DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
  666. core_if->op_state = A_HOST;
  667. dwc_otg_core_init(core_if);
  668. dwc_otg_enable_global_interrupts(core_if);
  669. cil_hcd_start(core_if);
  670. }
  671. /**
  672. * Frees secondary storage associated with the dwc_otg_hcd structure contained
  673. * in the struct usb_hcd field.
  674. */
  675. static void dwc_otg_hcd_free(dwc_otg_hcd_t * dwc_otg_hcd)
  676. {
  677. int i;
  678. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
  679. del_timers(dwc_otg_hcd);
  680. /* Free memory for QH/QTD lists */
  681. qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive);
  682. qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active);
  683. qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive);
  684. qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready);
  685. qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned);
  686. qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued);
  687. /* Free memory for the host channels. */
  688. for (i = 0; i < MAX_EPS_CHANNELS; i++) {
  689. dwc_hc_t *hc = dwc_otg_hcd->hc_ptr_array[i];
  690. #ifdef DEBUG
  691. if (dwc_otg_hcd->core_if->hc_xfer_timer[i]) {
  692. DWC_TIMER_FREE(dwc_otg_hcd->core_if->hc_xfer_timer[i]);
  693. }
  694. #endif
  695. if (hc != NULL) {
  696. DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n",
  697. i, hc);
  698. DWC_FREE(hc);
  699. }
  700. }
  701. if (dwc_otg_hcd->core_if->dma_enable) {
  702. if (dwc_otg_hcd->status_buf_dma) {
  703. DWC_DMA_FREE(DWC_OTG_HCD_STATUS_BUF_SIZE,
  704. dwc_otg_hcd->status_buf,
  705. dwc_otg_hcd->status_buf_dma);
  706. }
  707. } else if (dwc_otg_hcd->status_buf != NULL) {
  708. DWC_FREE(dwc_otg_hcd->status_buf);
  709. }
  710. DWC_SPINLOCK_FREE(dwc_otg_hcd->lock);
  711. /* Set core_if's lock pointer to NULL */
  712. dwc_otg_hcd->core_if->lock = NULL;
  713. DWC_TIMER_FREE(dwc_otg_hcd->conn_timer);
  714. DWC_TASK_FREE(dwc_otg_hcd->reset_tasklet);
  715. #ifdef DWC_DEV_SRPCAP
  716. if (dwc_otg_hcd->core_if->power_down == 2 &&
  717. dwc_otg_hcd->core_if->pwron_timer) {
  718. DWC_TIMER_FREE(dwc_otg_hcd->core_if->pwron_timer);
  719. }
  720. #endif
  721. DWC_FREE(dwc_otg_hcd);
  722. }
  723. int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd, dwc_otg_core_if_t * core_if)
  724. {
  725. int retval = 0;
  726. int num_channels;
  727. int i;
  728. dwc_hc_t *channel;
  729. hcd->lock = DWC_SPINLOCK_ALLOC();
  730. if (!hcd->lock) {
  731. DWC_ERROR("Could not allocate lock for pcd");
  732. DWC_FREE(hcd);
  733. retval = -DWC_E_NO_MEMORY;
  734. goto out;
  735. }
  736. hcd->core_if = core_if;
  737. /* Register the HCD CIL Callbacks */
  738. dwc_otg_cil_register_hcd_callbacks(hcd->core_if,
  739. &hcd_cil_callbacks, hcd);
  740. /* Initialize the non-periodic schedule. */
  741. DWC_LIST_INIT(&hcd->non_periodic_sched_inactive);
  742. DWC_LIST_INIT(&hcd->non_periodic_sched_active);
  743. /* Initialize the periodic schedule. */
  744. DWC_LIST_INIT(&hcd->periodic_sched_inactive);
  745. DWC_LIST_INIT(&hcd->periodic_sched_ready);
  746. DWC_LIST_INIT(&hcd->periodic_sched_assigned);
  747. DWC_LIST_INIT(&hcd->periodic_sched_queued);
  748. /*
  749. * Create a host channel descriptor for each host channel implemented
  750. * in the controller. Initialize the channel descriptor array.
  751. */
  752. DWC_CIRCLEQ_INIT(&hcd->free_hc_list);
  753. num_channels = hcd->core_if->core_params->host_channels;
  754. DWC_MEMSET(hcd->hc_ptr_array, 0, sizeof(hcd->hc_ptr_array));
  755. for (i = 0; i < num_channels; i++) {
  756. channel = DWC_ALLOC(sizeof(dwc_hc_t));
  757. if (channel == NULL) {
  758. retval = -DWC_E_NO_MEMORY;
  759. DWC_ERROR("%s: host channel allocation failed\n",
  760. __func__);
  761. dwc_otg_hcd_free(hcd);
  762. goto out;
  763. }
  764. channel->hc_num = i;
  765. hcd->hc_ptr_array[i] = channel;
  766. #ifdef DEBUG
  767. hcd->core_if->hc_xfer_timer[i] =
  768. DWC_TIMER_ALLOC("hc timer", hc_xfer_timeout,
  769. &hcd->core_if->hc_xfer_info[i]);
  770. #endif
  771. DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i,
  772. channel);
  773. }
  774. /* Initialize the Connection timeout timer. */
  775. hcd->conn_timer = DWC_TIMER_ALLOC("Connection timer",
  776. dwc_otg_hcd_connect_timeout, 0);
  777. /* Initialize reset tasklet. */
  778. hcd->reset_tasklet = DWC_TASK_ALLOC("reset_tasklet", reset_tasklet_func, hcd);
  779. #ifdef DWC_DEV_SRPCAP
  780. if (hcd->core_if->power_down == 2) {
  781. /* Initialize Power on timer for Host power up in case hibernation */
  782. hcd->core_if->pwron_timer = DWC_TIMER_ALLOC("PWRON TIMER",
  783. dwc_otg_hcd_power_up, core_if);
  784. }
  785. #endif
  786. /*
  787. * Allocate space for storing data on status transactions. Normally no
  788. * data is sent, but this space acts as a bit bucket. This must be
  789. * done after usb_add_hcd since that function allocates the DMA buffer
  790. * pool.
  791. */
  792. if (hcd->core_if->dma_enable) {
  793. hcd->status_buf =
  794. DWC_DMA_ALLOC(DWC_OTG_HCD_STATUS_BUF_SIZE,
  795. &hcd->status_buf_dma);
  796. } else {
  797. hcd->status_buf = DWC_ALLOC(DWC_OTG_HCD_STATUS_BUF_SIZE);
  798. }
  799. if (!hcd->status_buf) {
  800. retval = -DWC_E_NO_MEMORY;
  801. DWC_ERROR("%s: status_buf allocation failed\n", __func__);
  802. dwc_otg_hcd_free(hcd);
  803. goto out;
  804. }
  805. hcd->otg_port = 1;
  806. hcd->frame_list = NULL;
  807. hcd->frame_list_dma = 0;
  808. hcd->periodic_qh_count = 0;
  809. out:
  810. return retval;
  811. }
  812. void dwc_otg_hcd_remove(dwc_otg_hcd_t * hcd)
  813. {
  814. /* Turn off all host-specific interrupts. */
  815. dwc_otg_disable_host_interrupts(hcd->core_if);
  816. dwc_otg_hcd_free(hcd);
  817. }
  818. /**
  819. * Initializes dynamic portions of the DWC_otg HCD state.
  820. */
  821. static void dwc_otg_hcd_reinit(dwc_otg_hcd_t * hcd)
  822. {
  823. int num_channels;
  824. int i;
  825. dwc_hc_t *channel;
  826. dwc_hc_t *channel_tmp;
  827. hcd->flags.d32 = 0;
  828. hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active;
  829. hcd->non_periodic_channels = 0;
  830. hcd->periodic_channels = 0;
  831. /*
  832. * Put all channels in the free channel list and clean up channel
  833. * states.
  834. */
  835. DWC_CIRCLEQ_FOREACH_SAFE(channel, channel_tmp,
  836. &hcd->free_hc_list, hc_list_entry) {
  837. DWC_CIRCLEQ_REMOVE(&hcd->free_hc_list, channel, hc_list_entry);
  838. }
  839. num_channels = hcd->core_if->core_params->host_channels;
  840. for (i = 0; i < num_channels; i++) {
  841. channel = hcd->hc_ptr_array[i];
  842. DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, channel,
  843. hc_list_entry);
  844. dwc_otg_hc_cleanup(hcd->core_if, channel);
  845. }
  846. /* Initialize the DWC core for host mode operation. */
  847. dwc_otg_core_host_init(hcd->core_if);
  848. /* Set core_if's lock pointer to the hcd->lock */
  849. hcd->core_if->lock = hcd->lock;
  850. }
  851. /**
  852. * Assigns transactions from a QTD to a free host channel and initializes the
  853. * host channel to perform the transactions. The host channel is removed from
  854. * the free list.
  855. *
  856. * @param hcd The HCD state structure.
  857. * @param qh Transactions from the first QTD for this QH are selected and
  858. * assigned to a free host channel.
  859. */
  860. static void assign_and_init_hc(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
  861. {
  862. dwc_hc_t *hc;
  863. dwc_otg_qtd_t *qtd;
  864. dwc_otg_hcd_urb_t *urb;
  865. void* ptr = NULL;
  866. DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, hcd, qh);
  867. hc = DWC_CIRCLEQ_FIRST(&hcd->free_hc_list);
  868. /* Remove the host channel from the free list. */
  869. DWC_CIRCLEQ_REMOVE_INIT(&hcd->free_hc_list, hc, hc_list_entry);
  870. qtd = DWC_CIRCLEQ_FIRST(&qh->qtd_list);
  871. urb = qtd->urb;
  872. qh->channel = hc;
  873. qtd->in_process = 1;
  874. /*
  875. * Use usb_pipedevice to determine device address. This address is
  876. * 0 before the SET_ADDRESS command and the correct address afterward.
  877. */
  878. hc->dev_addr = dwc_otg_hcd_get_dev_addr(&urb->pipe_info);
  879. hc->ep_num = dwc_otg_hcd_get_ep_num(&urb->pipe_info);
  880. hc->speed = qh->dev_speed;
  881. hc->max_packet = dwc_max_packet(qh->maxp);
  882. hc->xfer_started = 0;
  883. hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
  884. hc->error_state = (qtd->error_count > 0);
  885. hc->halt_on_queue = 0;
  886. hc->halt_pending = 0;
  887. hc->requests = 0;
  888. /*
  889. * The following values may be modified in the transfer type section
  890. * below. The xfer_len value may be reduced when the transfer is
  891. * started to accommodate the max widths of the XferSize and PktCnt
  892. * fields in the HCTSIZn register.
  893. */
  894. hc->ep_is_in = (dwc_otg_hcd_is_pipe_in(&urb->pipe_info) != 0);
  895. if (hc->ep_is_in) {
  896. hc->do_ping = 0;
  897. } else {
  898. hc->do_ping = qh->ping_state;
  899. }
  900. hc->data_pid_start = qh->data_toggle;
  901. hc->multi_count = 1;
  902. if (hcd->core_if->dma_enable) {
  903. hc->xfer_buff = (uint8_t *) urb->dma + urb->actual_length;
  904. /* For non-dword aligned case */
  905. if (((unsigned long)hc->xfer_buff & 0x3)
  906. && !hcd->core_if->dma_desc_enable) {
  907. ptr = (uint8_t *) urb->buf + urb->actual_length;
  908. }
  909. } else {
  910. hc->xfer_buff = (uint8_t *) urb->buf + urb->actual_length;
  911. }
  912. hc->xfer_len = urb->length - urb->actual_length;
  913. hc->xfer_count = 0;
  914. /*
  915. * Set the split attributes
  916. */
  917. hc->do_split = 0;
  918. if (qh->do_split) {
  919. uint32_t hub_addr, port_addr;
  920. hc->do_split = 1;
  921. hc->xact_pos = qtd->isoc_split_pos;
  922. hc->complete_split = qtd->complete_split;
  923. hcd->fops->hub_info(hcd, urb->priv, &hub_addr, &port_addr);
  924. hc->hub_addr = (uint8_t) hub_addr;
  925. hc->port_addr = (uint8_t) port_addr;
  926. }
  927. switch (dwc_otg_hcd_get_pipe_type(&urb->pipe_info)) {
  928. case UE_CONTROL:
  929. hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
  930. switch (qtd->control_phase) {
  931. case DWC_OTG_CONTROL_SETUP:
  932. DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n");
  933. hc->do_ping = 0;
  934. hc->ep_is_in = 0;
  935. hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
  936. if (hcd->core_if->dma_enable) {
  937. hc->xfer_buff = (uint8_t *) urb->setup_dma;
  938. } else {
  939. hc->xfer_buff = (uint8_t *) urb->setup_packet;
  940. }
  941. hc->xfer_len = 8;
  942. ptr = NULL;
  943. break;
  944. case DWC_OTG_CONTROL_DATA:
  945. DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
  946. hc->data_pid_start = qtd->data_toggle;
  947. break;
  948. case DWC_OTG_CONTROL_STATUS:
  949. /*
  950. * Direction is opposite of data direction or IN if no
  951. * data.
  952. */
  953. DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n");
  954. if (urb->length == 0) {
  955. hc->ep_is_in = 1;
  956. } else {
  957. hc->ep_is_in =
  958. dwc_otg_hcd_is_pipe_out(&urb->pipe_info);
  959. }
  960. if (hc->ep_is_in) {
  961. hc->do_ping = 0;
  962. }
  963. hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
  964. hc->xfer_len = 0;
  965. if (hcd->core_if->dma_enable) {
  966. hc->xfer_buff = (uint8_t *) hcd->status_buf_dma;
  967. } else {
  968. hc->xfer_buff = (uint8_t *) hcd->status_buf;
  969. }
  970. ptr = NULL;
  971. break;
  972. }
  973. break;
  974. case UE_BULK:
  975. hc->ep_type = DWC_OTG_EP_TYPE_BULK;
  976. break;
  977. case UE_INTERRUPT:
  978. hc->ep_type = DWC_OTG_EP_TYPE_INTR;
  979. break;
  980. case UE_ISOCHRONOUS:
  981. {
  982. struct dwc_otg_hcd_iso_packet_desc *frame_desc;
  983. hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
  984. if (hcd->core_if->dma_desc_enable)
  985. break;
  986. frame_desc = &urb->iso_descs[qtd->isoc_frame_index];
  987. frame_desc->status = 0;
  988. if (hcd->core_if->dma_enable) {
  989. hc->xfer_buff = (uint8_t *) urb->dma;
  990. } else {
  991. hc->xfer_buff = (uint8_t *) urb->buf;
  992. }
  993. hc->xfer_buff +=
  994. frame_desc->offset + qtd->isoc_split_offset;
  995. hc->xfer_len =
  996. frame_desc->length - qtd->isoc_split_offset;
  997. /* For non-dword aligned buffers */
  998. if (((unsigned long)hc->xfer_buff & 0x3)
  999. && hcd->core_if->dma_enable) {
  1000. ptr =
  1001. (uint8_t *) urb->buf + frame_desc->offset +
  1002. qtd->isoc_split_offset;
  1003. } else
  1004. ptr = NULL;
  1005. if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
  1006. if (hc->xfer_len <= 188) {
  1007. hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
  1008. } else {
  1009. hc->xact_pos =
  1010. DWC_HCSPLIT_XACTPOS_BEGIN;
  1011. }
  1012. }
  1013. }
  1014. break;
  1015. }
  1016. /* non DWORD-aligned buffer case */
  1017. if (ptr) {
  1018. uint32_t buf_size;
  1019. if (hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
  1020. buf_size = hcd->core_if->core_params->max_transfer_size;
  1021. } else {
  1022. buf_size = 4096;
  1023. }
  1024. if (!qh->dw_align_buf) {
  1025. qh->dw_align_buf = DWC_DMA_ALLOC_ATOMIC(buf_size,
  1026. &qh->dw_align_buf_dma);
  1027. if (!qh->dw_align_buf) {
  1028. DWC_ERROR
  1029. ("%s: Failed to allocate memory to handle "
  1030. "non-dword aligned buffer case\n",
  1031. __func__);
  1032. return;
  1033. }
  1034. }
  1035. if (!hc->ep_is_in) {
  1036. dwc_memcpy(qh->dw_align_buf, ptr, hc->xfer_len);
  1037. }
  1038. hc->align_buff = qh->dw_align_buf_dma;
  1039. } else {
  1040. hc->align_buff = 0;
  1041. }
  1042. if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
  1043. hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
  1044. /*
  1045. * This value may be modified when the transfer is started to
  1046. * reflect the actual transfer length.
  1047. */
  1048. hc->multi_count = dwc_hb_mult(qh->maxp);
  1049. }
  1050. if (hcd->core_if->dma_desc_enable)
  1051. hc->desc_list_addr = qh->desc_list_dma;
  1052. dwc_otg_hc_init(hcd->core_if, hc);
  1053. hc->qh = qh;
  1054. }
  1055. /**
  1056. * This function selects transactions from the HCD transfer schedule and
  1057. * assigns them to available host channels. It is called from HCD interrupt
  1058. * handler functions.
  1059. *
  1060. * @param hcd The HCD state structure.
  1061. *
  1062. * @return The types of new transactions that were assigned to host channels.
  1063. */
  1064. dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t * hcd)
  1065. {
  1066. dwc_list_link_t *qh_ptr;
  1067. dwc_otg_qh_t *qh;
  1068. int num_channels;
  1069. dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
  1070. #ifdef DEBUG_SOF
  1071. DWC_DEBUGPL(DBG_HCD, " Select Transactions\n");
  1072. #endif
  1073. /* Process entries in the periodic ready list. */
  1074. qh_ptr = DWC_LIST_FIRST(&hcd->periodic_sched_ready);
  1075. while (qh_ptr != &hcd->periodic_sched_ready &&
  1076. !DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
  1077. qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
  1078. assign_and_init_hc(hcd, qh);
  1079. /*
  1080. * Move the QH from the periodic ready schedule to the
  1081. * periodic assigned schedule.
  1082. */
  1083. qh_ptr = DWC_LIST_NEXT(qh_ptr);
  1084. DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_assigned,
  1085. &qh->qh_list_entry);
  1086. ret_val = DWC_OTG_TRANSACTION_PERIODIC;
  1087. }
  1088. /*
  1089. * Process entries in the inactive portion of the non-periodic
  1090. * schedule. Some free host channels may not be used if they are
  1091. * reserved for periodic transfers.
  1092. */
  1093. qh_ptr = hcd->non_periodic_sched_inactive.next;
  1094. num_channels = hcd->core_if->core_params->host_channels;
  1095. while (qh_ptr != &hcd->non_periodic_sched_inactive &&
  1096. (hcd->non_periodic_channels <
  1097. num_channels - hcd->periodic_channels) &&
  1098. !DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
  1099. qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
  1100. assign_and_init_hc(hcd, qh);
  1101. /*
  1102. * Move the QH from the non-periodic inactive schedule to the
  1103. * non-periodic active schedule.
  1104. */
  1105. qh_ptr = DWC_LIST_NEXT(qh_ptr);
  1106. DWC_LIST_MOVE_HEAD(&hcd->non_periodic_sched_active,
  1107. &qh->qh_list_entry);
  1108. if (ret_val == DWC_OTG_TRANSACTION_NONE) {
  1109. ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
  1110. } else {
  1111. ret_val = DWC_OTG_TRANSACTION_ALL;
  1112. }
  1113. hcd->non_periodic_channels++;
  1114. }
  1115. return ret_val;
  1116. }
  1117. /**
  1118. * Attempts to queue a single transaction request for a host channel
  1119. * associated with either a periodic or non-periodic transfer. This function
  1120. * assumes that there is space available in the appropriate request queue. For
  1121. * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
  1122. * is available in the appropriate Tx FIFO.
  1123. *
  1124. * @param hcd The HCD state structure.
  1125. * @param hc Host channel descriptor associated with either a periodic or
  1126. * non-periodic transfer.
  1127. * @param fifo_dwords_avail Number of DWORDs available in the periodic Tx
  1128. * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
  1129. * transfers.
  1130. *
  1131. * @return 1 if a request is queued and more requests may be needed to
  1132. * complete the transfer, 0 if no more requests are required for this
  1133. * transfer, -1 if there is insufficient space in the Tx FIFO.
  1134. */
  1135. static int queue_transaction(dwc_otg_hcd_t * hcd,
  1136. dwc_hc_t * hc, uint16_t fifo_dwords_avail)
  1137. {
  1138. int retval;
  1139. if (hcd->core_if->dma_enable) {
  1140. if (hcd->core_if->dma_desc_enable) {
  1141. if (!hc->xfer_started
  1142. || (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)) {
  1143. dwc_otg_hcd_start_xfer_ddma(hcd, hc->qh);
  1144. hc->qh->ping_state = 0;
  1145. }
  1146. } else if (!hc->xfer_started) {
  1147. dwc_otg_hc_start_transfer(hcd->core_if, hc);
  1148. hc->qh->ping_state = 0;
  1149. }
  1150. retval = 0;
  1151. } else if (hc->halt_pending) {
  1152. /* Don't queue a request if the channel has been halted. */
  1153. retval = 0;
  1154. } else if (hc->halt_on_queue) {
  1155. dwc_otg_hc_halt(hcd->core_if, hc, hc->halt_status);
  1156. retval = 0;
  1157. } else if (hc->do_ping) {
  1158. if (!hc->xfer_started) {
  1159. dwc_otg_hc_start_transfer(hcd->core_if, hc);
  1160. }
  1161. retval = 0;
  1162. } else if (!hc->ep_is_in || hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
  1163. if ((fifo_dwords_avail * 4) >= hc->max_packet) {
  1164. if (!hc->xfer_started) {
  1165. dwc_otg_hc_start_transfer(hcd->core_if, hc);
  1166. retval = 1;
  1167. } else {
  1168. retval =
  1169. dwc_otg_hc_continue_transfer(hcd->core_if,
  1170. hc);
  1171. }
  1172. } else {
  1173. retval = -1;
  1174. }
  1175. } else {
  1176. if (!hc->xfer_started) {
  1177. dwc_otg_hc_start_transfer(hcd->core_if, hc);
  1178. retval = 1;
  1179. } else {
  1180. retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
  1181. }
  1182. }
  1183. return retval;
  1184. }
  1185. /**
  1186. * Processes periodic channels for the next frame and queues transactions for
  1187. * these channels to the DWC_otg controller. After queueing transactions, the
  1188. * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
  1189. * to queue as Periodic Tx FIFO or request queue space becomes available.
  1190. * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
  1191. */
  1192. static void process_periodic_channels(dwc_otg_hcd_t * hcd)
  1193. {
  1194. hptxsts_data_t tx_status;
  1195. dwc_list_link_t *qh_ptr;
  1196. dwc_otg_qh_t *qh;
  1197. int status;
  1198. int no_queue_space = 0;
  1199. int no_fifo_space = 0;
  1200. dwc_otg_host_global_regs_t *host_regs;
  1201. host_regs = hcd->core_if->host_if->host_global_regs;
  1202. DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
  1203. #ifdef DEBUG
  1204. tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
  1205. DWC_DEBUGPL(DBG_HCDV,
  1206. " P Tx Req Queue Space Avail (before queue): %d\n",
  1207. tx_status.b.ptxqspcavail);
  1208. DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n",
  1209. tx_status.b.ptxfspcavail);
  1210. #endif
  1211. qh_ptr = hcd->periodic_sched_assigned.next;
  1212. while (qh_ptr != &hcd->periodic_sched_assigned) {
  1213. tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
  1214. if (tx_status.b.ptxqspcavail == 0) {
  1215. no_queue_space = 1;
  1216. break;
  1217. }
  1218. qh = DWC_LIST_ENTRY(qh_ptr, dwc_otg_qh_t, qh_list_entry);
  1219. /*
  1220. * Set a flag if we're queuing high-bandwidth in slave mode.
  1221. * The flag prevents any halts to get into the request queue in
  1222. * the middle of multiple high-bandwidth packets getting queued.
  1223. */
  1224. if (!hcd->core_if->dma_enable && qh->channel->multi_count > 1) {
  1225. hcd->core_if->queuing_high_bandwidth = 1;
  1226. }
  1227. status =
  1228. queue_transaction(hcd, qh->channel,
  1229. tx_status.b.ptxfspcavail);
  1230. if (status < 0) {
  1231. no_fifo_space = 1;
  1232. break;
  1233. }
  1234. /*
  1235. * In Slave mode, stay on the current transfer until there is
  1236. * nothing more to do or the high-bandwidth request count is
  1237. * reached. In DMA mode, only need to queue one request. The
  1238. * controller automatically handles multiple packets for
  1239. * high-bandwidth transfers.
  1240. */
  1241. if (hcd->core_if->dma_enable || status == 0 ||
  1242. qh->channel->requests == qh->channel->multi_count) {
  1243. qh_ptr = qh_ptr->next;
  1244. /*
  1245. * Move the QH from the periodic assigned schedule to
  1246. * the periodic queued schedule.
  1247. */
  1248. DWC_LIST_MOVE_HEAD(&hcd->periodic_sched_queued,
  1249. &qh->qh_list_entry);
  1250. /* done queuing high bandwidth */
  1251. hcd->core_if->queuing_high_bandwidth = 0;
  1252. }
  1253. }
  1254. if (!hcd->core_if->dma_enable) {
  1255. dwc_otg_core_global_regs_t *global_regs;
  1256. gintmsk_data_t intr_mask = {.d32 = 0 };
  1257. global_regs = hcd->core_if->core_global_regs;
  1258. intr_mask.b.ptxfempty = 1;
  1259. #ifdef DEBUG
  1260. tx_status.d32 = DWC_READ_REG32(&host_regs->hptxsts);
  1261. DWC_DEBUGPL(DBG_HCDV,
  1262. " P Tx Req Queue Space Avail (after queue): %d\n",
  1263. tx_status.b.ptxqspcavail);
  1264. DWC_DEBUGPL(DBG_HCDV,
  1265. " P Tx FIFO Space Avail (after queue): %d\n",
  1266. tx_status.b.ptxfspcavail);
  1267. #endif
  1268. if (!DWC_LIST_EMPTY(&hcd->periodic_sched_assigned) ||
  1269. no_queue_space || no_fifo_space) {
  1270. /*
  1271. * May need to queue more transactions as the request
  1272. * queue or Tx FIFO empties. Enable the periodic Tx
  1273. * FIFO empty interrupt. (Always use the half-empty
  1274. * level to ensure that new requests are loaded as
  1275. * soon as possible.)
  1276. */
  1277. DWC_MODIFY_REG32(&global_regs->gintmsk, 0,
  1278. intr_mask.d32);
  1279. } else {
  1280. /*
  1281. * Disable the Tx FIFO empty interrupt since there are
  1282. * no more transactions that need to be queued right
  1283. * now. This function is called from interrupt
  1284. * handlers to queue more transactions as transfer
  1285. * states change.
  1286. */
  1287. DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32,
  1288. 0);
  1289. }
  1290. }
  1291. }
  1292. /**
  1293. * Processes active non-periodic channels and queues transactions for these
  1294. * channels to the DWC_otg controller. After queueing transactions, the NP Tx
  1295. * FIFO Empty interrupt is enabled if there are more transactions to queue as
  1296. * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
  1297. * FIFO Empty interrupt is disabled.
  1298. */
  1299. static void process_non_periodic_channels(dwc_otg_hcd_t * hcd)
  1300. {
  1301. gnptxsts_data_t tx_status;
  1302. dwc_list_link_t *orig_qh_ptr;
  1303. dwc_otg_qh_t *qh;
  1304. int status;
  1305. int no_queue_space = 0;
  1306. int no_fifo_space = 0;
  1307. int more_to_do = 0;
  1308. dwc_otg_core_global_regs_t *global_regs =
  1309. hcd->core_if->core_global_regs;
  1310. DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
  1311. #ifdef DEBUG
  1312. tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
  1313. DWC_DEBUGPL(DBG_HCDV,
  1314. " NP Tx Req Queue Space Avail (before queue): %d\n",
  1315. tx_status.b.nptxqspcavail);
  1316. DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n",
  1317. tx_status.b.nptxfspcavail);
  1318. #endif
  1319. /*
  1320. * Keep track of the starting point. Skip over the start-of-list
  1321. * entry.
  1322. */
  1323. if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
  1324. hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
  1325. }
  1326. orig_qh_ptr = hcd->non_periodic_qh_ptr;
  1327. /*
  1328. * Process once through the active list or until no more space is
  1329. * available in the request queue or the Tx FIFO.
  1330. */
  1331. do {
  1332. tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
  1333. if (!hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) {
  1334. no_queue_space = 1;
  1335. break;
  1336. }
  1337. qh = DWC_LIST_ENTRY(hcd->non_periodic_qh_ptr, dwc_otg_qh_t,
  1338. qh_list_entry);
  1339. status =
  1340. queue_transaction(hcd, qh->channel,
  1341. tx_status.b.nptxfspcavail);
  1342. if (status > 0) {
  1343. more_to_do = 1;
  1344. } else if (status < 0) {
  1345. no_fifo_space = 1;
  1346. break;
  1347. }
  1348. /* Advance to next QH, skipping start-of-list entry. */
  1349. hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
  1350. if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
  1351. hcd->non_periodic_qh_ptr =
  1352. hcd->non_periodic_qh_ptr->next;
  1353. }
  1354. } while (hcd->non_periodic_qh_ptr != orig_qh_ptr);
  1355. if (!hcd->core_if->dma_enable) {
  1356. gintmsk_data_t intr_mask = {.d32 = 0 };
  1357. intr_mask.b.nptxfempty = 1;
  1358. #ifdef DEBUG
  1359. tx_status.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
  1360. DWC_DEBUGPL(DBG_HCDV,
  1361. " NP Tx Req Queue Space Avail (after queue): %d\n",
  1362. tx_status.b.nptxqspcavail);
  1363. DWC_DEBUGPL(DBG_HCDV,
  1364. " NP Tx FIFO Space Avail (after queue): %d\n",
  1365. tx_status.b.nptxfspcavail);
  1366. #endif
  1367. if (more_to_do || no_queue_space || no_fifo_space) {
  1368. /*
  1369. * May need to queue more transactions as the request
  1370. * queue or Tx FIFO empties. Enable the non-periodic
  1371. * Tx FIFO empty interrupt. (Always use the half-empty
  1372. * level to ensure that new requests are loaded as
  1373. * soon as possible.)
  1374. */
  1375. DWC_MODIFY_REG32(&global_regs->gintmsk, 0,
  1376. intr_mask.d32);
  1377. } else {
  1378. /*
  1379. * Disable the Tx FIFO empty interrupt since there are
  1380. * no more transactions that need to be queued right
  1381. * now. This function is called from interrupt
  1382. * handlers to queue more transactions as transfer
  1383. * states change.
  1384. */
  1385. DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32,
  1386. 0);
  1387. }
  1388. }
  1389. }
  1390. /**
  1391. * This function processes the currently active host channels and queues
  1392. * transactions for these channels to the DWC_otg controller. It is called
  1393. * from HCD interrupt handler functions.
  1394. *
  1395. * @param hcd The HCD state structure.
  1396. * @param tr_type The type(s) of transactions to queue (non-periodic,
  1397. * periodic, or both).
  1398. */
  1399. void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t * hcd,
  1400. dwc_otg_transaction_type_e tr_type)
  1401. {
  1402. #ifdef DEBUG_SOF
  1403. DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
  1404. #endif
  1405. /* Process host channels associated with periodic transfers. */
  1406. if ((tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
  1407. tr_type == DWC_OTG_TRANSACTION_ALL) &&
  1408. !DWC_LIST_EMPTY(&hcd->periodic_sched_assigned)) {
  1409. process_periodic_channels(hcd);
  1410. }
  1411. /* Process host channels associated with non-periodic transfers. */
  1412. if (tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
  1413. tr_type == DWC_OTG_TRANSACTION_ALL) {
  1414. if (!DWC_LIST_EMPTY(&hcd->non_periodic_sched_active)) {
  1415. process_non_periodic_channels(hcd);
  1416. } else {
  1417. /*
  1418. * Ensure NP Tx FIFO empty interrupt is disabled when
  1419. * there are no non-periodic transfers to process.
  1420. */
  1421. gintmsk_data_t gintmsk = {.d32 = 0 };
  1422. gintmsk.b.nptxfempty = 1;
  1423. DWC_MODIFY_REG32(&hcd->core_if->
  1424. core_global_regs->gintmsk, gintmsk.d32,
  1425. 0);
  1426. }
  1427. }
  1428. }
  1429. #ifdef DWC_HS_ELECT_TST
  1430. /*
  1431. * Quick and dirty hack to implement the HS Electrical Test
  1432. * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
  1433. *
  1434. * This code was copied from our userspace app "hset". It sends a
  1435. * Get Device Descriptor control sequence in two parts, first the
  1436. * Setup packet by itself, followed some time later by the In and
  1437. * Ack packets. Rather than trying to figure out how to add this
  1438. * functionality to the normal driver code, we just hijack the
  1439. * hardware, using these two function to drive the hardware
  1440. * directly.
  1441. */
  1442. static dwc_otg_core_global_regs_t *global_regs;
  1443. static dwc_otg_host_global_regs_t *hc_global_regs;
  1444. static dwc_otg_hc_regs_t *hc_regs;
  1445. static uint32_t *data_fifo;
  1446. static void do_setup(void)
  1447. {
  1448. gintsts_data_t gintsts;
  1449. hctsiz_data_t hctsiz;
  1450. hcchar_data_t hcchar;
  1451. haint_data_t haint;
  1452. hcint_data_t hcint;
  1453. /* Enable HAINTs */
  1454. DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0001);
  1455. /* Enable HCINTs */
  1456. DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x04a3);
  1457. /* Read GINTSTS */
  1458. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1459. /* Read HAINT */
  1460. haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
  1461. /* Read HCINT */
  1462. hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
  1463. /* Read HCCHAR */
  1464. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1465. /* Clear HCINT */
  1466. DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
  1467. /* Clear HAINT */
  1468. DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
  1469. /* Clear GINTSTS */
  1470. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1471. /* Read GINTSTS */
  1472. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1473. /*
  1474. * Send Setup packet (Get Device Descriptor)
  1475. */
  1476. /* Make sure channel is disabled */
  1477. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1478. if (hcchar.b.chen) {
  1479. hcchar.b.chdis = 1;
  1480. // hcchar.b.chen = 1;
  1481. DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
  1482. //sleep(1);
  1483. dwc_mdelay(1000);
  1484. /* Read GINTSTS */
  1485. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1486. /* Read HAINT */
  1487. haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
  1488. /* Read HCINT */
  1489. hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
  1490. /* Read HCCHAR */
  1491. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1492. /* Clear HCINT */
  1493. DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
  1494. /* Clear HAINT */
  1495. DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
  1496. /* Clear GINTSTS */
  1497. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1498. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1499. }
  1500. /* Set HCTSIZ */
  1501. hctsiz.d32 = 0;
  1502. hctsiz.b.xfersize = 8;
  1503. hctsiz.b.pktcnt = 1;
  1504. hctsiz.b.pid = DWC_OTG_HC_PID_SETUP;
  1505. DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
  1506. /* Set HCCHAR */
  1507. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1508. hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
  1509. hcchar.b.epdir = 0;
  1510. hcchar.b.epnum = 0;
  1511. hcchar.b.mps = 8;
  1512. hcchar.b.chen = 1;
  1513. DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
  1514. /* Fill FIFO with Setup data for Get Device Descriptor */
  1515. data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
  1516. DWC_WRITE_REG32(data_fifo++, 0x01000680);
  1517. DWC_WRITE_REG32(data_fifo++, 0x00080000);
  1518. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1519. /* Wait for host channel interrupt */
  1520. do {
  1521. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1522. } while (gintsts.b.hcintr == 0);
  1523. /* Disable HCINTs */
  1524. DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x0000);
  1525. /* Disable HAINTs */
  1526. DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0000);
  1527. /* Read HAINT */
  1528. haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
  1529. /* Read HCINT */
  1530. hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
  1531. /* Read HCCHAR */
  1532. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1533. /* Clear HCINT */
  1534. DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
  1535. /* Clear HAINT */
  1536. DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
  1537. /* Clear GINTSTS */
  1538. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1539. /* Read GINTSTS */
  1540. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1541. }
  1542. static void do_in_ack(void)
  1543. {
  1544. gintsts_data_t gintsts;
  1545. hctsiz_data_t hctsiz;
  1546. hcchar_data_t hcchar;
  1547. haint_data_t haint;
  1548. hcint_data_t hcint;
  1549. host_grxsts_data_t grxsts;
  1550. /* Enable HAINTs */
  1551. DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0001);
  1552. /* Enable HCINTs */
  1553. DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x04a3);
  1554. /* Read GINTSTS */
  1555. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1556. /* Read HAINT */
  1557. haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
  1558. /* Read HCINT */
  1559. hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
  1560. /* Read HCCHAR */
  1561. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1562. /* Clear HCINT */
  1563. DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
  1564. /* Clear HAINT */
  1565. DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
  1566. /* Clear GINTSTS */
  1567. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1568. /* Read GINTSTS */
  1569. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1570. /*
  1571. * Receive Control In packet
  1572. */
  1573. /* Make sure channel is disabled */
  1574. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1575. if (hcchar.b.chen) {
  1576. hcchar.b.chdis = 1;
  1577. hcchar.b.chen = 1;
  1578. DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
  1579. //sleep(1);
  1580. dwc_mdelay(1000);
  1581. /* Read GINTSTS */
  1582. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1583. /* Read HAINT */
  1584. haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
  1585. /* Read HCINT */
  1586. hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
  1587. /* Read HCCHAR */
  1588. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1589. /* Clear HCINT */
  1590. DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
  1591. /* Clear HAINT */
  1592. DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
  1593. /* Clear GINTSTS */
  1594. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1595. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1596. }
  1597. /* Set HCTSIZ */
  1598. hctsiz.d32 = 0;
  1599. hctsiz.b.xfersize = 8;
  1600. hctsiz.b.pktcnt = 1;
  1601. hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
  1602. DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
  1603. /* Set HCCHAR */
  1604. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1605. hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
  1606. hcchar.b.epdir = 1;
  1607. hcchar.b.epnum = 0;
  1608. hcchar.b.mps = 8;
  1609. hcchar.b.chen = 1;
  1610. DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
  1611. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1612. /* Wait for receive status queue interrupt */
  1613. do {
  1614. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1615. } while (gintsts.b.rxstsqlvl == 0);
  1616. /* Read RXSTS */
  1617. grxsts.d32 = DWC_READ_REG32(&global_regs->grxstsp);
  1618. /* Clear RXSTSQLVL in GINTSTS */
  1619. gintsts.d32 = 0;
  1620. gintsts.b.rxstsqlvl = 1;
  1621. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1622. switch (grxsts.b.pktsts) {
  1623. case DWC_GRXSTS_PKTSTS_IN:
  1624. /* Read the data into the host buffer */
  1625. if (grxsts.b.bcnt > 0) {
  1626. int i;
  1627. int word_count = (grxsts.b.bcnt + 3) / 4;
  1628. data_fifo = (uint32_t *) ((char *)global_regs + 0x1000);
  1629. for (i = 0; i < word_count; i++) {
  1630. (void)DWC_READ_REG32(data_fifo++);
  1631. }
  1632. }
  1633. break;
  1634. default:
  1635. break;
  1636. }
  1637. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1638. /* Wait for receive status queue interrupt */
  1639. do {
  1640. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1641. } while (gintsts.b.rxstsqlvl == 0);
  1642. /* Read RXSTS */
  1643. grxsts.d32 = DWC_READ_REG32(&global_regs->grxstsp);
  1644. /* Clear RXSTSQLVL in GINTSTS */
  1645. gintsts.d32 = 0;
  1646. gintsts.b.rxstsqlvl = 1;
  1647. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1648. switch (grxsts.b.pktsts) {
  1649. case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
  1650. break;
  1651. default:
  1652. break;
  1653. }
  1654. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1655. /* Wait for host channel interrupt */
  1656. do {
  1657. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1658. } while (gintsts.b.hcintr == 0);
  1659. /* Read HAINT */
  1660. haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
  1661. /* Read HCINT */
  1662. hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
  1663. /* Read HCCHAR */
  1664. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1665. /* Clear HCINT */
  1666. DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
  1667. /* Clear HAINT */
  1668. DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
  1669. /* Clear GINTSTS */
  1670. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1671. /* Read GINTSTS */
  1672. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1673. // usleep(100000);
  1674. // mdelay(100);
  1675. dwc_mdelay(1);
  1676. /*
  1677. * Send handshake packet
  1678. */
  1679. /* Read HAINT */
  1680. haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
  1681. /* Read HCINT */
  1682. hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
  1683. /* Read HCCHAR */
  1684. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1685. /* Clear HCINT */
  1686. DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
  1687. /* Clear HAINT */
  1688. DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
  1689. /* Clear GINTSTS */
  1690. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1691. /* Read GINTSTS */
  1692. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1693. /* Make sure channel is disabled */
  1694. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1695. if (hcchar.b.chen) {
  1696. hcchar.b.chdis = 1;
  1697. hcchar.b.chen = 1;
  1698. DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
  1699. //sleep(1);
  1700. dwc_mdelay(1000);
  1701. /* Read GINTSTS */
  1702. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1703. /* Read HAINT */
  1704. haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
  1705. /* Read HCINT */
  1706. hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
  1707. /* Read HCCHAR */
  1708. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1709. /* Clear HCINT */
  1710. DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
  1711. /* Clear HAINT */
  1712. DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
  1713. /* Clear GINTSTS */
  1714. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1715. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1716. }
  1717. /* Set HCTSIZ */
  1718. hctsiz.d32 = 0;
  1719. hctsiz.b.xfersize = 0;
  1720. hctsiz.b.pktcnt = 1;
  1721. hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
  1722. DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
  1723. /* Set HCCHAR */
  1724. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1725. hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
  1726. hcchar.b.epdir = 0;
  1727. hcchar.b.epnum = 0;
  1728. hcchar.b.mps = 8;
  1729. hcchar.b.chen = 1;
  1730. DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
  1731. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1732. /* Wait for host channel interrupt */
  1733. do {
  1734. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1735. } while (gintsts.b.hcintr == 0);
  1736. /* Disable HCINTs */
  1737. DWC_WRITE_REG32(&hc_regs->hcintmsk, 0x0000);
  1738. /* Disable HAINTs */
  1739. DWC_WRITE_REG32(&hc_global_regs->haintmsk, 0x0000);
  1740. /* Read HAINT */
  1741. haint.d32 = DWC_READ_REG32(&hc_global_regs->haint);
  1742. /* Read HCINT */
  1743. hcint.d32 = DWC_READ_REG32(&hc_regs->hcint);
  1744. /* Read HCCHAR */
  1745. hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
  1746. /* Clear HCINT */
  1747. DWC_WRITE_REG32(&hc_regs->hcint, hcint.d32);
  1748. /* Clear HAINT */
  1749. DWC_WRITE_REG32(&hc_global_regs->haint, haint.d32);
  1750. /* Clear GINTSTS */
  1751. DWC_WRITE_REG32(&global_regs->gintsts, gintsts.d32);
  1752. /* Read GINTSTS */
  1753. gintsts.d32 = DWC_READ_REG32(&global_regs->gintsts);
  1754. }
  1755. #endif
  1756. /** Handles hub class-specific requests. */
  1757. int dwc_otg_hcd_hub_control(dwc_otg_hcd_t * dwc_otg_hcd,
  1758. uint16_t typeReq,
  1759. uint16_t wValue,
  1760. uint16_t wIndex, uint8_t * buf, uint16_t wLength)
  1761. {
  1762. int retval = 0;
  1763. dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
  1764. usb_hub_descriptor_t *hub_desc;
  1765. hprt0_data_t hprt0 = {.d32 = 0 };
  1766. uint32_t port_status;
  1767. switch (typeReq) {
  1768. case UCR_CLEAR_HUB_FEATURE:
  1769. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1770. "ClearHubFeature 0x%x\n", wValue);
  1771. switch (wValue) {
  1772. case UHF_C_HUB_LOCAL_POWER:
  1773. case UHF_C_HUB_OVER_CURRENT:
  1774. /* Nothing required here */
  1775. break;
  1776. default:
  1777. retval = -DWC_E_INVALID;
  1778. DWC_ERROR("DWC OTG HCD - "
  1779. "ClearHubFeature request %xh unknown\n",
  1780. wValue);
  1781. }
  1782. break;
  1783. case UCR_CLEAR_PORT_FEATURE:
  1784. #ifdef CONFIG_USB_DWC_OTG_LPM
  1785. if (wValue != UHF_PORT_L1)
  1786. #endif
  1787. if (!wIndex || wIndex > 1)
  1788. goto error;
  1789. switch (wValue) {
  1790. case UHF_PORT_ENABLE:
  1791. DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - "
  1792. "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
  1793. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  1794. hprt0.b.prtena = 1;
  1795. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  1796. break;
  1797. case UHF_PORT_SUSPEND:
  1798. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1799. "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
  1800. if (core_if->power_down == 2) {
  1801. dwc_otg_host_hibernation_restore(core_if, 0, 0);
  1802. } else {
  1803. DWC_WRITE_REG32(core_if->pcgcctl, 0);
  1804. dwc_mdelay(5);
  1805. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  1806. hprt0.b.prtres = 1;
  1807. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  1808. hprt0.b.prtsusp = 0;
  1809. /* Clear Resume bit */
  1810. dwc_mdelay(100);
  1811. hprt0.b.prtres = 0;
  1812. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  1813. }
  1814. break;
  1815. #ifdef CONFIG_USB_DWC_OTG_LPM
  1816. case UHF_PORT_L1:
  1817. {
  1818. pcgcctl_data_t pcgcctl = {.d32 = 0 };
  1819. glpmcfg_data_t lpmcfg = {.d32 = 0 };
  1820. lpmcfg.d32 =
  1821. DWC_READ_REG32(&core_if->
  1822. core_global_regs->glpmcfg);
  1823. lpmcfg.b.en_utmi_sleep = 0;
  1824. lpmcfg.b.hird_thres &= (~(1 << 4));
  1825. lpmcfg.b.prt_sleep_sts = 1;
  1826. DWC_WRITE_REG32(&core_if->
  1827. core_global_regs->glpmcfg,
  1828. lpmcfg.d32);
  1829. /* Clear Enbl_L1Gating bit. */
  1830. pcgcctl.b.enbl_sleep_gating = 1;
  1831. DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32,
  1832. 0);
  1833. dwc_mdelay(5);
  1834. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  1835. hprt0.b.prtres = 1;
  1836. DWC_WRITE_REG32(core_if->host_if->hprt0,
  1837. hprt0.d32);
  1838. /* This bit will be cleared in wakeup interrupt handle */
  1839. break;
  1840. }
  1841. #endif
  1842. case UHF_PORT_POWER:
  1843. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1844. "ClearPortFeature USB_PORT_FEAT_POWER\n");
  1845. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  1846. hprt0.b.prtpwr = 0;
  1847. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  1848. break;
  1849. case UHF_PORT_INDICATOR:
  1850. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1851. "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
  1852. /* Port inidicator not supported */
  1853. break;
  1854. case UHF_C_PORT_CONNECTION:
  1855. /* Clears drivers internal connect status change
  1856. * flag */
  1857. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1858. "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
  1859. dwc_otg_hcd->flags.b.port_connect_status_change = 0;
  1860. break;
  1861. case UHF_C_PORT_RESET:
  1862. /* Clears the driver's internal Port Reset Change
  1863. * flag */
  1864. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1865. "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
  1866. dwc_otg_hcd->flags.b.port_reset_change = 0;
  1867. break;
  1868. case UHF_C_PORT_ENABLE:
  1869. /* Clears the driver's internal Port
  1870. * Enable/Disable Change flag */
  1871. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1872. "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
  1873. dwc_otg_hcd->flags.b.port_enable_change = 0;
  1874. break;
  1875. case UHF_C_PORT_SUSPEND:
  1876. /* Clears the driver's internal Port Suspend
  1877. * Change flag, which is set when resume signaling on
  1878. * the host port is complete */
  1879. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1880. "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
  1881. dwc_otg_hcd->flags.b.port_suspend_change = 0;
  1882. break;
  1883. #ifdef CONFIG_USB_DWC_OTG_LPM
  1884. case UHF_C_PORT_L1:
  1885. dwc_otg_hcd->flags.b.port_l1_change = 0;
  1886. break;
  1887. #endif
  1888. case UHF_C_PORT_OVER_CURRENT:
  1889. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1890. "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
  1891. dwc_otg_hcd->flags.b.port_over_current_change = 0;
  1892. break;
  1893. default:
  1894. retval = -DWC_E_INVALID;
  1895. DWC_ERROR("DWC OTG HCD - "
  1896. "ClearPortFeature request %xh "
  1897. "unknown or unsupported\n", wValue);
  1898. }
  1899. break;
  1900. case UCR_GET_HUB_DESCRIPTOR:
  1901. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1902. "GetHubDescriptor\n");
  1903. hub_desc = (usb_hub_descriptor_t *) buf;
  1904. hub_desc->bDescLength = 9;
  1905. hub_desc->bDescriptorType = 0x29;
  1906. hub_desc->bNbrPorts = 1;
  1907. USETW(hub_desc->wHubCharacteristics, 0x08);
  1908. hub_desc->bPwrOn2PwrGood = 1;
  1909. hub_desc->bHubContrCurrent = 0;
  1910. hub_desc->DeviceRemovable[0] = 0;
  1911. hub_desc->DeviceRemovable[1] = 0xff;
  1912. break;
  1913. case UCR_GET_HUB_STATUS:
  1914. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1915. "GetHubStatus\n");
  1916. DWC_MEMSET(buf, 0, 4);
  1917. break;
  1918. case UCR_GET_PORT_STATUS:
  1919. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1920. "GetPortStatus wIndex = 0x%04x FLAGS=0x%08x\n",
  1921. wIndex, dwc_otg_hcd->flags.d32);
  1922. if (!wIndex || wIndex > 1)
  1923. goto error;
  1924. port_status = 0;
  1925. if (dwc_otg_hcd->flags.b.port_connect_status_change)
  1926. port_status |= (1 << UHF_C_PORT_CONNECTION);
  1927. if (dwc_otg_hcd->flags.b.port_enable_change)
  1928. port_status |= (1 << UHF_C_PORT_ENABLE);
  1929. if (dwc_otg_hcd->flags.b.port_suspend_change)
  1930. port_status |= (1 << UHF_C_PORT_SUSPEND);
  1931. if (dwc_otg_hcd->flags.b.port_l1_change)
  1932. port_status |= (1 << UHF_C_PORT_L1);
  1933. if (dwc_otg_hcd->flags.b.port_reset_change) {
  1934. port_status |= (1 << UHF_C_PORT_RESET);
  1935. }
  1936. if (dwc_otg_hcd->flags.b.port_over_current_change) {
  1937. DWC_WARN("Overcurrent change detected\n");
  1938. port_status |= (1 << UHF_C_PORT_OVER_CURRENT);
  1939. }
  1940. if (!dwc_otg_hcd->flags.b.port_connect_status) {
  1941. /*
  1942. * The port is disconnected, which means the core is
  1943. * either in device mode or it soon will be. Just
  1944. * return 0's for the remainder of the port status
  1945. * since the port register can't be read if the core
  1946. * is in device mode.
  1947. */
  1948. *((__le32 *) buf) = dwc_cpu_to_le32(&port_status);
  1949. break;
  1950. }
  1951. hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
  1952. DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
  1953. if (hprt0.b.prtconnsts)
  1954. port_status |= (1 << UHF_PORT_CONNECTION);
  1955. if (hprt0.b.prtena)
  1956. port_status |= (1 << UHF_PORT_ENABLE);
  1957. if (hprt0.b.prtsusp)
  1958. port_status |= (1 << UHF_PORT_SUSPEND);
  1959. if (hprt0.b.prtovrcurract)
  1960. port_status |= (1 << UHF_PORT_OVER_CURRENT);
  1961. if (hprt0.b.prtrst)
  1962. port_status |= (1 << UHF_PORT_RESET);
  1963. if (hprt0.b.prtpwr)
  1964. port_status |= (1 << UHF_PORT_POWER);
  1965. if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
  1966. port_status |= (1 << UHF_PORT_HIGH_SPEED);
  1967. else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
  1968. port_status |= (1 << UHF_PORT_LOW_SPEED);
  1969. if (hprt0.b.prttstctl)
  1970. port_status |= (1 << UHF_PORT_TEST);
  1971. if (dwc_otg_get_lpm_portsleepstatus(dwc_otg_hcd->core_if)) {
  1972. port_status |= (1 << UHF_PORT_L1);
  1973. }
  1974. /*
  1975. For Synopsys HW emulation of Power down wkup_control asserts the
  1976. hreset_n and prst_n on suspned. This causes the HPRT0 to be zero.
  1977. We intentionally tell the software that port is in L2Suspend state.
  1978. Only for STE.
  1979. */
  1980. if ((core_if->power_down == 2)
  1981. && (core_if->hibernation_suspend == 1)) {
  1982. port_status |= (1 << UHF_PORT_SUSPEND);
  1983. }
  1984. /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
  1985. *((__le32 *) buf) = dwc_cpu_to_le32(&port_status);
  1986. break;
  1987. case UCR_SET_HUB_FEATURE:
  1988. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  1989. "SetHubFeature\n");
  1990. /* No HUB features supported */
  1991. break;
  1992. case UCR_SET_PORT_FEATURE:
  1993. if (wValue != UHF_PORT_TEST && (!wIndex || wIndex > 1))
  1994. goto error;
  1995. if (!dwc_otg_hcd->flags.b.port_connect_status) {
  1996. /*
  1997. * The port is disconnected, which means the core is
  1998. * either in device mode or it soon will be. Just
  1999. * return without doing anything since the port
  2000. * register can't be written if the core is in device
  2001. * mode.
  2002. */
  2003. break;
  2004. }
  2005. switch (wValue) {
  2006. case UHF_PORT_SUSPEND:
  2007. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  2008. "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
  2009. if (dwc_otg_hcd_otg_port(dwc_otg_hcd) != wIndex) {
  2010. goto error;
  2011. }
  2012. if (core_if->power_down == 2) {
  2013. int timeout = 300;
  2014. dwc_irqflags_t flags;
  2015. pcgcctl_data_t pcgcctl = {.d32 = 0 };
  2016. gpwrdn_data_t gpwrdn = {.d32 = 0 };
  2017. gusbcfg_data_t gusbcfg = {.d32 = 0 };
  2018. #ifdef DWC_DEV_SRPCAP
  2019. int32_t otg_cap_param = core_if->core_params->otg_cap;
  2020. #endif
  2021. DWC_PRINTF("Preparing for complete power-off\n");
  2022. /* Save registers before hibernation */
  2023. dwc_otg_save_global_regs(core_if);
  2024. dwc_otg_save_host_regs(core_if);
  2025. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  2026. hprt0.b.prtsusp = 1;
  2027. hprt0.b.prtena = 0;
  2028. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  2029. /* Spin hprt0.b.prtsusp to became 1 */
  2030. do {
  2031. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  2032. if (hprt0.b.prtsusp) {
  2033. break;
  2034. }
  2035. dwc_mdelay(1);
  2036. } while (--timeout);
  2037. if (!timeout) {
  2038. DWC_WARN("Suspend wasn't genereted\n");
  2039. }
  2040. dwc_udelay(10);
  2041. /*
  2042. * We need to disable interrupts to prevent servicing of any IRQ
  2043. * during going to hibernation
  2044. */
  2045. DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
  2046. core_if->lx_state = DWC_OTG_L2;
  2047. #ifdef DWC_DEV_SRPCAP
  2048. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  2049. hprt0.b.prtpwr = 0;
  2050. hprt0.b.prtena = 0;
  2051. DWC_WRITE_REG32(core_if->host_if->hprt0,
  2052. hprt0.d32);
  2053. #endif
  2054. gusbcfg.d32 =
  2055. DWC_READ_REG32(&core_if->core_global_regs->
  2056. gusbcfg);
  2057. if (gusbcfg.b.ulpi_utmi_sel == 1) {
  2058. /* ULPI interface */
  2059. /* Suspend the Phy Clock */
  2060. pcgcctl.d32 = 0;
  2061. pcgcctl.b.stoppclk = 1;
  2062. DWC_MODIFY_REG32(core_if->pcgcctl, 0,
  2063. pcgcctl.d32);
  2064. dwc_udelay(10);
  2065. gpwrdn.b.pmuactv = 1;
  2066. DWC_MODIFY_REG32(&core_if->
  2067. core_global_regs->
  2068. gpwrdn, 0, gpwrdn.d32);
  2069. } else {
  2070. /* UTMI+ Interface */
  2071. gpwrdn.b.pmuactv = 1;
  2072. DWC_MODIFY_REG32(&core_if->
  2073. core_global_regs->
  2074. gpwrdn, 0, gpwrdn.d32);
  2075. dwc_udelay(10);
  2076. pcgcctl.b.stoppclk = 1;
  2077. DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32);
  2078. dwc_udelay(10);
  2079. }
  2080. #ifdef DWC_DEV_SRPCAP
  2081. gpwrdn.d32 = 0;
  2082. gpwrdn.b.dis_vbus = 1;
  2083. DWC_MODIFY_REG32(&core_if->core_global_regs->
  2084. gpwrdn, 0, gpwrdn.d32);
  2085. #endif
  2086. gpwrdn.d32 = 0;
  2087. gpwrdn.b.pmuintsel = 1;
  2088. DWC_MODIFY_REG32(&core_if->core_global_regs->
  2089. gpwrdn, 0, gpwrdn.d32);
  2090. dwc_udelay(10);
  2091. gpwrdn.d32 = 0;
  2092. #ifdef DWC_DEV_SRPCAP
  2093. gpwrdn.b.srp_det_msk = 1;
  2094. #endif
  2095. gpwrdn.b.disconn_det_msk = 1;
  2096. gpwrdn.b.lnstchng_msk = 1;
  2097. gpwrdn.b.sts_chngint_msk = 1;
  2098. DWC_MODIFY_REG32(&core_if->core_global_regs->
  2099. gpwrdn, 0, gpwrdn.d32);
  2100. dwc_udelay(10);
  2101. /* Enable Power Down Clamp and all interrupts in GPWRDN */
  2102. gpwrdn.d32 = 0;
  2103. gpwrdn.b.pwrdnclmp = 1;
  2104. DWC_MODIFY_REG32(&core_if->core_global_regs->
  2105. gpwrdn, 0, gpwrdn.d32);
  2106. dwc_udelay(10);
  2107. /* Switch off VDD */
  2108. gpwrdn.d32 = 0;
  2109. gpwrdn.b.pwrdnswtch = 1;
  2110. DWC_MODIFY_REG32(&core_if->core_global_regs->
  2111. gpwrdn, 0, gpwrdn.d32);
  2112. #ifdef DWC_DEV_SRPCAP
  2113. if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE)
  2114. {
  2115. core_if->pwron_timer_started = 1;
  2116. DWC_TIMER_SCHEDULE(core_if->pwron_timer, 6000 /* 6 secs */ );
  2117. }
  2118. #endif
  2119. /* Save gpwrdn register for further usage if stschng interrupt */
  2120. core_if->gr_backup->gpwrdn_local =
  2121. DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
  2122. /* Set flag to indicate that we are in hibernation */
  2123. core_if->hibernation_suspend = 1;
  2124. DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock,flags);
  2125. DWC_PRINTF("Host hibernation completed\n");
  2126. // Exit from case statement
  2127. break;
  2128. }
  2129. if (dwc_otg_hcd_otg_port(dwc_otg_hcd) == wIndex &&
  2130. dwc_otg_hcd->fops->get_b_hnp_enable(dwc_otg_hcd)) {
  2131. gotgctl_data_t gotgctl = {.d32 = 0 };
  2132. gotgctl.b.hstsethnpen = 1;
  2133. DWC_MODIFY_REG32(&core_if->core_global_regs->
  2134. gotgctl, 0, gotgctl.d32);
  2135. core_if->op_state = A_SUSPEND;
  2136. }
  2137. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  2138. hprt0.b.prtsusp = 1;
  2139. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  2140. {
  2141. dwc_irqflags_t flags;
  2142. /* Update lx_state */
  2143. DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
  2144. core_if->lx_state = DWC_OTG_L2;
  2145. DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
  2146. }
  2147. /* Suspend the Phy Clock */
  2148. {
  2149. pcgcctl_data_t pcgcctl = {.d32 = 0 };
  2150. pcgcctl.b.stoppclk = 1;
  2151. DWC_MODIFY_REG32(core_if->pcgcctl, 0,
  2152. pcgcctl.d32);
  2153. dwc_udelay(10);
  2154. }
  2155. /* For HNP the bus must be suspended for at least 200ms. */
  2156. if (dwc_otg_hcd->fops->get_b_hnp_enable(dwc_otg_hcd)) {
  2157. pcgcctl_data_t pcgcctl = {.d32 = 0 };
  2158. pcgcctl.b.stoppclk = 1;
  2159. DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
  2160. dwc_mdelay(200);
  2161. }
  2162. /** @todo - check how sw can wait for 1 sec to check asesvld??? */
  2163. #if 0 //vahrama !!!!!!!!!!!!!!!!!!
  2164. if (core_if->adp_enable) {
  2165. gotgctl_data_t gotgctl = {.d32 = 0 };
  2166. gpwrdn_data_t gpwrdn;
  2167. while (gotgctl.b.asesvld == 1) {
  2168. gotgctl.d32 =
  2169. DWC_READ_REG32(&core_if->
  2170. core_global_regs->
  2171. gotgctl);
  2172. dwc_mdelay(100);
  2173. }
  2174. /* Enable Power Down Logic */
  2175. gpwrdn.d32 = 0;
  2176. gpwrdn.b.pmuactv = 1;
  2177. DWC_MODIFY_REG32(&core_if->core_global_regs->
  2178. gpwrdn, 0, gpwrdn.d32);
  2179. /* Unmask SRP detected interrupt from Power Down Logic */
  2180. gpwrdn.d32 = 0;
  2181. gpwrdn.b.srp_det_msk = 1;
  2182. DWC_MODIFY_REG32(&core_if->core_global_regs->
  2183. gpwrdn, 0, gpwrdn.d32);
  2184. dwc_otg_adp_probe_start(core_if);
  2185. }
  2186. #endif
  2187. break;
  2188. case UHF_PORT_POWER:
  2189. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  2190. "SetPortFeature - USB_PORT_FEAT_POWER\n");
  2191. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  2192. hprt0.b.prtpwr = 1;
  2193. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  2194. break;
  2195. case UHF_PORT_RESET:
  2196. if ((core_if->power_down == 2)
  2197. && (core_if->hibernation_suspend == 1)) {
  2198. /* If we are going to exit from Hibernated
  2199. * state via USB RESET.
  2200. */
  2201. dwc_otg_host_hibernation_restore(core_if, 0, 1);
  2202. } else {
  2203. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  2204. DWC_DEBUGPL(DBG_HCD,
  2205. "DWC OTG HCD HUB CONTROL - "
  2206. "SetPortFeature - USB_PORT_FEAT_RESET\n");
  2207. {
  2208. pcgcctl_data_t pcgcctl = {.d32 = 0 };
  2209. pcgcctl.b.enbl_sleep_gating = 1;
  2210. pcgcctl.b.stoppclk = 1;
  2211. DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
  2212. DWC_WRITE_REG32(core_if->pcgcctl, 0);
  2213. }
  2214. #ifdef CONFIG_USB_DWC_OTG_LPM
  2215. {
  2216. glpmcfg_data_t lpmcfg;
  2217. lpmcfg.d32 =
  2218. DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
  2219. if (lpmcfg.b.prt_sleep_sts) {
  2220. lpmcfg.b.en_utmi_sleep = 0;
  2221. lpmcfg.b.hird_thres &= (~(1 << 4));
  2222. DWC_WRITE_REG32
  2223. (&core_if->core_global_regs->glpmcfg,
  2224. lpmcfg.d32);
  2225. dwc_mdelay(1);
  2226. }
  2227. }
  2228. #endif
  2229. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  2230. /* Clear suspend bit if resetting from suspended state. */
  2231. hprt0.b.prtsusp = 0;
  2232. /* When B-Host the Port reset bit is set in
  2233. * the Start HCD Callback function, so that
  2234. * the reset is started within 1ms of the HNP
  2235. * success interrupt. */
  2236. if (!dwc_otg_hcd_is_b_host(dwc_otg_hcd)) {
  2237. hprt0.b.prtpwr = 1;
  2238. hprt0.b.prtrst = 1;
  2239. DWC_PRINTF("Indeed it is in host mode hprt0 = %08x\n",hprt0.d32);
  2240. DWC_WRITE_REG32(core_if->host_if->hprt0,
  2241. hprt0.d32);
  2242. }
  2243. /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
  2244. dwc_mdelay(60);
  2245. hprt0.b.prtrst = 0;
  2246. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  2247. core_if->lx_state = DWC_OTG_L0; /* Now back to the on state */
  2248. }
  2249. break;
  2250. #ifdef DWC_HS_ELECT_TST
  2251. case UHF_PORT_TEST:
  2252. {
  2253. uint32_t t;
  2254. gintmsk_data_t gintmsk;
  2255. t = (wIndex >> 8); /* MSB wIndex USB */
  2256. DWC_DEBUGPL(DBG_HCD,
  2257. "DWC OTG HCD HUB CONTROL - "
  2258. "SetPortFeature - USB_PORT_FEAT_TEST %d\n",
  2259. t);
  2260. DWC_WARN("USB_PORT_FEAT_TEST %d\n", t);
  2261. if (t < 6) {
  2262. hprt0.d32 = dwc_otg_read_hprt0(core_if);
  2263. hprt0.b.prttstctl = t;
  2264. DWC_WRITE_REG32(core_if->host_if->hprt0,
  2265. hprt0.d32);
  2266. } else {
  2267. /* Setup global vars with reg addresses (quick and
  2268. * dirty hack, should be cleaned up)
  2269. */
  2270. global_regs = core_if->core_global_regs;
  2271. hc_global_regs =
  2272. core_if->host_if->host_global_regs;
  2273. hc_regs =
  2274. (dwc_otg_hc_regs_t *) ((char *)
  2275. global_regs +
  2276. 0x500);
  2277. data_fifo =
  2278. (uint32_t *) ((char *)global_regs +
  2279. 0x1000);
  2280. if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */
  2281. /* Save current interrupt mask */
  2282. gintmsk.d32 =
  2283. DWC_READ_REG32
  2284. (&global_regs->gintmsk);
  2285. /* Disable all interrupts while we muck with
  2286. * the hardware directly
  2287. */
  2288. DWC_WRITE_REG32(&global_regs->gintmsk, 0);
  2289. /* 15 second delay per the test spec */
  2290. dwc_mdelay(15000);
  2291. /* Drive suspend on the root port */
  2292. hprt0.d32 =
  2293. dwc_otg_read_hprt0(core_if);
  2294. hprt0.b.prtsusp = 1;
  2295. hprt0.b.prtres = 0;
  2296. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  2297. /* 15 second delay per the test spec */
  2298. dwc_mdelay(15000);
  2299. /* Drive resume on the root port */
  2300. hprt0.d32 =
  2301. dwc_otg_read_hprt0(core_if);
  2302. hprt0.b.prtsusp = 0;
  2303. hprt0.b.prtres = 1;
  2304. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  2305. dwc_mdelay(100);
  2306. /* Clear the resume bit */
  2307. hprt0.b.prtres = 0;
  2308. DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
  2309. /* Restore interrupts */
  2310. DWC_WRITE_REG32(&global_regs->gintmsk, gintmsk.d32);
  2311. } else if (t == 7) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
  2312. /* Save current interrupt mask */
  2313. gintmsk.d32 =
  2314. DWC_READ_REG32
  2315. (&global_regs->gintmsk);
  2316. /* Disable all interrupts while we muck with
  2317. * the hardware directly
  2318. */
  2319. DWC_WRITE_REG32(&global_regs->gintmsk, 0);
  2320. /* 15 second delay per the test spec */
  2321. dwc_mdelay(15000);
  2322. /* Send the Setup packet */
  2323. do_setup();
  2324. /* 15 second delay so nothing else happens for awhile */
  2325. dwc_mdelay(15000);
  2326. /* Restore interrupts */
  2327. DWC_WRITE_REG32(&global_regs->gintmsk, gintmsk.d32);
  2328. } else if (t == 8) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
  2329. /* Save current interrupt mask */
  2330. gintmsk.d32 =
  2331. DWC_READ_REG32
  2332. (&global_regs->gintmsk);
  2333. /* Disable all interrupts while we muck with
  2334. * the hardware directly
  2335. */
  2336. DWC_WRITE_REG32(&global_regs->gintmsk, 0);
  2337. /* Send the Setup packet */
  2338. do_setup();
  2339. /* 15 second delay so nothing else happens for awhile */
  2340. dwc_mdelay(15000);
  2341. /* Send the In and Ack packets */
  2342. do_in_ack();
  2343. /* 15 second delay so nothing else happens for awhile */
  2344. dwc_mdelay(15000);
  2345. /* Restore interrupts */
  2346. DWC_WRITE_REG32(&global_regs->gintmsk, gintmsk.d32);
  2347. }
  2348. }
  2349. break;
  2350. }
  2351. #endif /* DWC_HS_ELECT_TST */
  2352. case UHF_PORT_INDICATOR:
  2353. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  2354. "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
  2355. /* Not supported */
  2356. break;
  2357. default:
  2358. retval = -DWC_E_INVALID;
  2359. DWC_ERROR("DWC OTG HCD - "
  2360. "SetPortFeature request %xh "
  2361. "unknown or unsupported\n", wValue);
  2362. break;
  2363. }
  2364. break;
  2365. #ifdef CONFIG_USB_DWC_OTG_LPM
  2366. case UCR_SET_AND_TEST_PORT_FEATURE:
  2367. if (wValue != UHF_PORT_L1) {
  2368. goto error;
  2369. }
  2370. {
  2371. int portnum, hird, devaddr, remwake;
  2372. glpmcfg_data_t lpmcfg;
  2373. uint32_t time_usecs;
  2374. gintsts_data_t gintsts;
  2375. gintmsk_data_t gintmsk;
  2376. if (!dwc_otg_get_param_lpm_enable(core_if)) {
  2377. goto error;
  2378. }
  2379. if (wValue != UHF_PORT_L1 || wLength != 1) {
  2380. goto error;
  2381. }
  2382. /* Check if the port currently is in SLEEP state */
  2383. lpmcfg.d32 =
  2384. DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
  2385. if (lpmcfg.b.prt_sleep_sts) {
  2386. DWC_INFO("Port is already in sleep mode\n");
  2387. buf[0] = 0; /* Return success */
  2388. break;
  2389. }
  2390. portnum = wIndex & 0xf;
  2391. hird = (wIndex >> 4) & 0xf;
  2392. devaddr = (wIndex >> 8) & 0x7f;
  2393. remwake = (wIndex >> 15);
  2394. if (portnum != 1) {
  2395. retval = -DWC_E_INVALID;
  2396. DWC_WARN
  2397. ("Wrong port number(%d) in SetandTestPortFeature request\n",
  2398. portnum);
  2399. break;
  2400. }
  2401. DWC_PRINTF
  2402. ("SetandTestPortFeature request: portnum = %d, hird = %d, devaddr = %d, rewake = %d\n",
  2403. portnum, hird, devaddr, remwake);
  2404. /* Disable LPM interrupt */
  2405. gintmsk.d32 = 0;
  2406. gintmsk.b.lpmtranrcvd = 1;
  2407. DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
  2408. gintmsk.d32, 0);
  2409. if (dwc_otg_hcd_send_lpm
  2410. (dwc_otg_hcd, devaddr, hird, remwake)) {
  2411. retval = -DWC_E_INVALID;
  2412. break;
  2413. }
  2414. time_usecs = 10 * (lpmcfg.b.retry_count + 1);
  2415. /* We will consider timeout if time_usecs microseconds pass,
  2416. * and we don't receive LPM transaction status.
  2417. * After receiving non-error responce(ACK/NYET/STALL) from device,
  2418. * core will set lpmtranrcvd bit.
  2419. */
  2420. do {
  2421. gintsts.d32 =
  2422. DWC_READ_REG32(&core_if->core_global_regs->gintsts);
  2423. if (gintsts.b.lpmtranrcvd) {
  2424. break;
  2425. }
  2426. dwc_udelay(1);
  2427. } while (--time_usecs);
  2428. /* lpm_int bit will be cleared in LPM interrupt handler */
  2429. /* Now fill status
  2430. * 0x00 - Success
  2431. * 0x10 - NYET
  2432. * 0x11 - Timeout
  2433. */
  2434. if (!gintsts.b.lpmtranrcvd) {
  2435. buf[0] = 0x3; /* Completion code is Timeout */
  2436. dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd);
  2437. } else {
  2438. lpmcfg.d32 =
  2439. DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
  2440. if (lpmcfg.b.lpm_resp == 0x3) {
  2441. /* ACK responce from the device */
  2442. buf[0] = 0x00; /* Success */
  2443. } else if (lpmcfg.b.lpm_resp == 0x2) {
  2444. /* NYET responce from the device */
  2445. buf[0] = 0x2;
  2446. } else {
  2447. /* Otherwise responce with Timeout */
  2448. buf[0] = 0x3;
  2449. }
  2450. }
  2451. DWC_PRINTF("Device responce to LPM trans is %x\n",
  2452. lpmcfg.b.lpm_resp);
  2453. DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0,
  2454. gintmsk.d32);
  2455. break;
  2456. }
  2457. #endif /* CONFIG_USB_DWC_OTG_LPM */
  2458. default:
  2459. error:
  2460. retval = -DWC_E_INVALID;
  2461. DWC_WARN("DWC OTG HCD - "
  2462. "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
  2463. typeReq, wIndex, wValue);
  2464. break;
  2465. }
  2466. return retval;
  2467. }
  2468. #ifdef CONFIG_USB_DWC_OTG_LPM
  2469. /** Returns index of host channel to perform LPM transaction. */
  2470. int dwc_otg_hcd_get_hc_for_lpm_tran(dwc_otg_hcd_t * hcd, uint8_t devaddr)
  2471. {
  2472. dwc_otg_core_if_t *core_if = hcd->core_if;
  2473. dwc_hc_t *hc;
  2474. hcchar_data_t hcchar;
  2475. gintmsk_data_t gintmsk = {.d32 = 0 };
  2476. if (DWC_CIRCLEQ_EMPTY(&hcd->free_hc_list)) {
  2477. DWC_PRINTF("No free channel to select for LPM transaction\n");
  2478. return -1;
  2479. }
  2480. hc = DWC_CIRCLEQ_FIRST(&hcd->free_hc_list);
  2481. /* Mask host channel interrupts. */
  2482. gintmsk.b.hcintr = 1;
  2483. DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
  2484. /* Fill fields that core needs for LPM transaction */
  2485. hcchar.b.devaddr = devaddr;
  2486. hcchar.b.epnum = 0;
  2487. hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
  2488. hcchar.b.mps = 64;
  2489. hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
  2490. hcchar.b.epdir = 0; /* OUT */
  2491. DWC_WRITE_REG32(&core_if->host_if->hc_regs[hc->hc_num]->hcchar,
  2492. hcchar.d32);
  2493. /* Remove the host channel from the free list. */
  2494. DWC_CIRCLEQ_REMOVE_INIT(&hcd->free_hc_list, hc, hc_list_entry);
  2495. DWC_PRINTF("hcnum = %d devaddr = %d\n", hc->hc_num, devaddr);
  2496. return hc->hc_num;
  2497. }
  2498. /** Release hc after performing LPM transaction */
  2499. void dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd_t * hcd)
  2500. {
  2501. dwc_hc_t *hc;
  2502. glpmcfg_data_t lpmcfg;
  2503. uint8_t hc_num;
  2504. lpmcfg.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->glpmcfg);
  2505. hc_num = lpmcfg.b.lpm_chan_index;
  2506. hc = hcd->hc_ptr_array[hc_num];
  2507. DWC_PRINTF("Freeing channel %d after LPM\n", hc_num);
  2508. /* Return host channel to free list */
  2509. DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry);
  2510. }
  2511. int dwc_otg_hcd_send_lpm(dwc_otg_hcd_t * hcd, uint8_t devaddr, uint8_t hird,
  2512. uint8_t bRemoteWake)
  2513. {
  2514. glpmcfg_data_t lpmcfg;
  2515. pcgcctl_data_t pcgcctl = {.d32 = 0 };
  2516. int channel;
  2517. channel = dwc_otg_hcd_get_hc_for_lpm_tran(hcd, devaddr);
  2518. if (channel < 0) {
  2519. return channel;
  2520. }
  2521. pcgcctl.b.enbl_sleep_gating = 1;
  2522. DWC_MODIFY_REG32(hcd->core_if->pcgcctl, 0, pcgcctl.d32);
  2523. /* Read LPM config register */
  2524. lpmcfg.d32 = DWC_READ_REG32(&hcd->core_if->core_global_regs->glpmcfg);
  2525. /* Program LPM transaction fields */
  2526. lpmcfg.b.rem_wkup_en = bRemoteWake;
  2527. lpmcfg.b.hird = hird;
  2528. lpmcfg.b.hird_thres = 0x1c;
  2529. lpmcfg.b.lpm_chan_index = channel;
  2530. lpmcfg.b.en_utmi_sleep = 1;
  2531. /* Program LPM config register */
  2532. DWC_WRITE_REG32(&hcd->core_if->core_global_regs->glpmcfg, lpmcfg.d32);
  2533. /* Send LPM transaction */
  2534. lpmcfg.b.send_lpm = 1;
  2535. DWC_WRITE_REG32(&hcd->core_if->core_global_regs->glpmcfg, lpmcfg.d32);
  2536. return 0;
  2537. }
  2538. #endif /* CONFIG_USB_DWC_OTG_LPM */
  2539. int dwc_otg_hcd_is_status_changed(dwc_otg_hcd_t * hcd, int port)
  2540. {
  2541. int retval;
  2542. if (port != 1) {
  2543. return -DWC_E_INVALID;
  2544. }
  2545. retval = (hcd->flags.b.port_connect_status_change ||
  2546. hcd->flags.b.port_reset_change ||
  2547. hcd->flags.b.port_enable_change ||
  2548. hcd->flags.b.port_suspend_change ||
  2549. hcd->flags.b.port_over_current_change);
  2550. #ifdef DEBUG
  2551. if (retval) {
  2552. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:"
  2553. " Root port status changed\n");
  2554. DWC_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
  2555. hcd->flags.b.port_connect_status_change);
  2556. DWC_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
  2557. hcd->flags.b.port_reset_change);
  2558. DWC_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
  2559. hcd->flags.b.port_enable_change);
  2560. DWC_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
  2561. hcd->flags.b.port_suspend_change);
  2562. DWC_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
  2563. hcd->flags.b.port_over_current_change);
  2564. }
  2565. #endif
  2566. return retval;
  2567. }
  2568. int dwc_otg_hcd_get_frame_number(dwc_otg_hcd_t * dwc_otg_hcd)
  2569. {
  2570. hfnum_data_t hfnum;
  2571. hfnum.d32 =
  2572. DWC_READ_REG32(&dwc_otg_hcd->core_if->host_if->host_global_regs->
  2573. hfnum);
  2574. #ifdef DEBUG_SOF
  2575. DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n",
  2576. hfnum.b.frnum);
  2577. #endif
  2578. return hfnum.b.frnum;
  2579. }
  2580. int dwc_otg_hcd_start(dwc_otg_hcd_t * hcd,
  2581. struct dwc_otg_hcd_function_ops *fops)
  2582. {
  2583. int retval = 0;
  2584. hcd->fops = fops;
  2585. if (!dwc_otg_is_device_mode(hcd->core_if) &&
  2586. (!hcd->core_if->adp_enable || hcd->core_if->adp.adp_started)) {
  2587. dwc_otg_hcd_reinit(hcd);
  2588. } else {
  2589. retval = -DWC_E_NO_DEVICE;
  2590. }
  2591. return retval;
  2592. }
  2593. void *dwc_otg_hcd_get_priv_data(dwc_otg_hcd_t * hcd)
  2594. {
  2595. return hcd->priv;
  2596. }
  2597. void dwc_otg_hcd_set_priv_data(dwc_otg_hcd_t * hcd, void *priv_data)
  2598. {
  2599. hcd->priv = priv_data;
  2600. }
  2601. uint32_t dwc_otg_hcd_otg_port(dwc_otg_hcd_t * hcd)
  2602. {
  2603. return hcd->otg_port;
  2604. }
  2605. uint32_t dwc_otg_hcd_is_b_host(dwc_otg_hcd_t * hcd)
  2606. {
  2607. uint32_t is_b_host;
  2608. if (hcd->core_if->op_state == B_HOST) {
  2609. is_b_host = 1;
  2610. } else {
  2611. is_b_host = 0;
  2612. }
  2613. return is_b_host;
  2614. }
  2615. dwc_otg_hcd_urb_t *dwc_otg_hcd_urb_alloc(dwc_otg_hcd_t * hcd,
  2616. int iso_desc_count, int atomic_alloc)
  2617. {
  2618. dwc_otg_hcd_urb_t *dwc_otg_urb;
  2619. uint32_t size;
  2620. size =
  2621. sizeof(*dwc_otg_urb) +
  2622. iso_desc_count * sizeof(struct dwc_otg_hcd_iso_packet_desc);
  2623. if (atomic_alloc)
  2624. dwc_otg_urb = DWC_ALLOC_ATOMIC(size);
  2625. else
  2626. dwc_otg_urb = DWC_ALLOC(size);
  2627. dwc_otg_urb->packet_count = iso_desc_count;
  2628. return dwc_otg_urb;
  2629. }
  2630. void dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_hcd_urb_t * dwc_otg_urb,
  2631. uint8_t dev_addr, uint8_t ep_num,
  2632. uint8_t ep_type, uint8_t ep_dir, uint16_t mps)
  2633. {
  2634. dwc_otg_hcd_fill_pipe(&dwc_otg_urb->pipe_info, dev_addr, ep_num,
  2635. ep_type, ep_dir, mps);
  2636. #if 0
  2637. DWC_PRINTF
  2638. ("addr = %d, ep_num = %d, ep_dir = 0x%x, ep_type = 0x%x, mps = %d\n",
  2639. dev_addr, ep_num, ep_dir, ep_type, mps);
  2640. #endif
  2641. }
  2642. void dwc_otg_hcd_urb_set_params(dwc_otg_hcd_urb_t * dwc_otg_urb,
  2643. void *urb_handle, void *buf, dwc_dma_t dma,
  2644. uint32_t buflen, void *setup_packet,
  2645. dwc_dma_t setup_dma, uint32_t flags,
  2646. uint16_t interval)
  2647. {
  2648. dwc_otg_urb->priv = urb_handle;
  2649. dwc_otg_urb->buf = buf;
  2650. dwc_otg_urb->dma = dma;
  2651. dwc_otg_urb->length = buflen;
  2652. dwc_otg_urb->setup_packet = setup_packet;
  2653. dwc_otg_urb->setup_dma = setup_dma;
  2654. dwc_otg_urb->flags = flags;
  2655. dwc_otg_urb->interval = interval;
  2656. dwc_otg_urb->status = -DWC_E_IN_PROGRESS;
  2657. }
  2658. uint32_t dwc_otg_hcd_urb_get_status(dwc_otg_hcd_urb_t * dwc_otg_urb)
  2659. {
  2660. return dwc_otg_urb->status;
  2661. }
  2662. uint32_t dwc_otg_hcd_urb_get_actual_length(dwc_otg_hcd_urb_t * dwc_otg_urb)
  2663. {
  2664. return dwc_otg_urb->actual_length;
  2665. }
  2666. uint32_t dwc_otg_hcd_urb_get_error_count(dwc_otg_hcd_urb_t * dwc_otg_urb)
  2667. {
  2668. return dwc_otg_urb->error_count;
  2669. }
  2670. void dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_hcd_urb_t * dwc_otg_urb,
  2671. int desc_num, uint32_t offset,
  2672. uint32_t length)
  2673. {
  2674. dwc_otg_urb->iso_descs[desc_num].offset = offset;
  2675. dwc_otg_urb->iso_descs[desc_num].length = length;
  2676. }
  2677. uint32_t dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_hcd_urb_t * dwc_otg_urb,
  2678. int desc_num)
  2679. {
  2680. return dwc_otg_urb->iso_descs[desc_num].status;
  2681. }
  2682. uint32_t dwc_otg_hcd_urb_get_iso_desc_actual_length(dwc_otg_hcd_urb_t *
  2683. dwc_otg_urb, int desc_num)
  2684. {
  2685. return dwc_otg_urb->iso_descs[desc_num].actual_length;
  2686. }
  2687. int dwc_otg_hcd_is_bandwidth_allocated(dwc_otg_hcd_t * hcd, void *ep_handle)
  2688. {
  2689. int allocated = 0;
  2690. dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
  2691. if (qh) {
  2692. if (!DWC_LIST_EMPTY(&qh->qh_list_entry)) {
  2693. allocated = 1;
  2694. }
  2695. }
  2696. return allocated;
  2697. }
  2698. int dwc_otg_hcd_is_bandwidth_freed(dwc_otg_hcd_t * hcd, void *ep_handle)
  2699. {
  2700. dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
  2701. int freed = 0;
  2702. DWC_ASSERT(qh, "qh is not allocated\n");
  2703. if (DWC_LIST_EMPTY(&qh->qh_list_entry)) {
  2704. freed = 1;
  2705. }
  2706. return freed;
  2707. }
  2708. uint8_t dwc_otg_hcd_get_ep_bandwidth(dwc_otg_hcd_t * hcd, void *ep_handle)
  2709. {
  2710. dwc_otg_qh_t *qh = (dwc_otg_qh_t *) ep_handle;
  2711. DWC_ASSERT(qh, "qh is not allocated\n");
  2712. return qh->usecs;
  2713. }
  2714. void dwc_otg_hcd_dump_state(dwc_otg_hcd_t * hcd)
  2715. {
  2716. #ifdef DEBUG
  2717. int num_channels;
  2718. int i;
  2719. gnptxsts_data_t np_tx_status;
  2720. hptxsts_data_t p_tx_status;
  2721. num_channels = hcd->core_if->core_params->host_channels;
  2722. DWC_PRINTF("\n");
  2723. DWC_PRINTF
  2724. ("************************************************************\n");
  2725. DWC_PRINTF("HCD State:\n");
  2726. DWC_PRINTF(" Num channels: %d\n", num_channels);
  2727. for (i = 0; i < num_channels; i++) {
  2728. dwc_hc_t *hc = hcd->hc_ptr_array[i];
  2729. DWC_PRINTF(" Channel %d:\n", i);
  2730. DWC_PRINTF(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
  2731. hc->dev_addr, hc->ep_num, hc->ep_is_in);
  2732. DWC_PRINTF(" speed: %d\n", hc->speed);
  2733. DWC_PRINTF(" ep_type: %d\n", hc->ep_type);
  2734. DWC_PRINTF(" max_packet: %d\n", hc->max_packet);
  2735. DWC_PRINTF(" data_pid_start: %d\n", hc->data_pid_start);
  2736. DWC_PRINTF(" multi_count: %d\n", hc->multi_count);
  2737. DWC_PRINTF(" xfer_started: %d\n", hc->xfer_started);
  2738. DWC_PRINTF(" xfer_buff: %p\n", hc->xfer_buff);
  2739. DWC_PRINTF(" xfer_len: %d\n", hc->xfer_len);
  2740. DWC_PRINTF(" xfer_count: %d\n", hc->xfer_count);
  2741. DWC_PRINTF(" halt_on_queue: %d\n", hc->halt_on_queue);
  2742. DWC_PRINTF(" halt_pending: %d\n", hc->halt_pending);
  2743. DWC_PRINTF(" halt_status: %d\n", hc->halt_status);
  2744. DWC_PRINTF(" do_split: %d\n", hc->do_split);
  2745. DWC_PRINTF(" complete_split: %d\n", hc->complete_split);
  2746. DWC_PRINTF(" hub_addr: %d\n", hc->hub_addr);
  2747. DWC_PRINTF(" port_addr: %d\n", hc->port_addr);
  2748. DWC_PRINTF(" xact_pos: %d\n", hc->xact_pos);
  2749. DWC_PRINTF(" requests: %d\n", hc->requests);
  2750. DWC_PRINTF(" qh: %p\n", hc->qh);
  2751. if (hc->xfer_started) {
  2752. hfnum_data_t hfnum;
  2753. hcchar_data_t hcchar;
  2754. hctsiz_data_t hctsiz;
  2755. hcint_data_t hcint;
  2756. hcintmsk_data_t hcintmsk;
  2757. hfnum.d32 =
  2758. DWC_READ_REG32(&hcd->core_if->
  2759. host_if->host_global_regs->hfnum);
  2760. hcchar.d32 =
  2761. DWC_READ_REG32(&hcd->core_if->host_if->
  2762. hc_regs[i]->hcchar);
  2763. hctsiz.d32 =
  2764. DWC_READ_REG32(&hcd->core_if->host_if->
  2765. hc_regs[i]->hctsiz);
  2766. hcint.d32 =
  2767. DWC_READ_REG32(&hcd->core_if->host_if->
  2768. hc_regs[i]->hcint);
  2769. hcintmsk.d32 =
  2770. DWC_READ_REG32(&hcd->core_if->host_if->
  2771. hc_regs[i]->hcintmsk);
  2772. DWC_PRINTF(" hfnum: 0x%08x\n", hfnum.d32);
  2773. DWC_PRINTF(" hcchar: 0x%08x\n", hcchar.d32);
  2774. DWC_PRINTF(" hctsiz: 0x%08x\n", hctsiz.d32);
  2775. DWC_PRINTF(" hcint: 0x%08x\n", hcint.d32);
  2776. DWC_PRINTF(" hcintmsk: 0x%08x\n", hcintmsk.d32);
  2777. }
  2778. if (hc->xfer_started && hc->qh) {
  2779. dwc_otg_qtd_t *qtd;
  2780. dwc_otg_hcd_urb_t *urb;
  2781. DWC_CIRCLEQ_FOREACH(qtd, &hc->qh->qtd_list, qtd_list_entry) {
  2782. if (!qtd->in_process)
  2783. break;
  2784. urb = qtd->urb;
  2785. DWC_PRINTF(" URB Info:\n");
  2786. DWC_PRINTF(" qtd: %p, urb: %p\n", qtd, urb);
  2787. if (urb) {
  2788. DWC_PRINTF(" Dev: %d, EP: %d %s\n",
  2789. dwc_otg_hcd_get_dev_addr(&urb->
  2790. pipe_info),
  2791. dwc_otg_hcd_get_ep_num(&urb->
  2792. pipe_info),
  2793. dwc_otg_hcd_is_pipe_in(&urb->
  2794. pipe_info) ?
  2795. "IN" : "OUT");
  2796. DWC_PRINTF(" Max packet size: %d\n",
  2797. dwc_otg_hcd_get_mps(&urb->
  2798. pipe_info));
  2799. DWC_PRINTF(" transfer_buffer: %p\n",
  2800. urb->buf);
  2801. DWC_PRINTF(" transfer_dma: %p\n",
  2802. (void *)urb->dma);
  2803. DWC_PRINTF(" transfer_buffer_length: %d\n",
  2804. urb->length);
  2805. DWC_PRINTF(" actual_length: %d\n",
  2806. urb->actual_length);
  2807. }
  2808. }
  2809. }
  2810. }
  2811. DWC_PRINTF(" non_periodic_channels: %d\n", hcd->non_periodic_channels);
  2812. DWC_PRINTF(" periodic_channels: %d\n", hcd->periodic_channels);
  2813. DWC_PRINTF(" periodic_usecs: %d\n", hcd->periodic_usecs);
  2814. np_tx_status.d32 =
  2815. DWC_READ_REG32(&hcd->core_if->core_global_regs->gnptxsts);
  2816. DWC_PRINTF(" NP Tx Req Queue Space Avail: %d\n",
  2817. np_tx_status.b.nptxqspcavail);
  2818. DWC_PRINTF(" NP Tx FIFO Space Avail: %d\n",
  2819. np_tx_status.b.nptxfspcavail);
  2820. p_tx_status.d32 =
  2821. DWC_READ_REG32(&hcd->core_if->host_if->host_global_regs->hptxsts);
  2822. DWC_PRINTF(" P Tx Req Queue Space Avail: %d\n",
  2823. p_tx_status.b.ptxqspcavail);
  2824. DWC_PRINTF(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
  2825. dwc_otg_hcd_dump_frrem(hcd);
  2826. dwc_otg_dump_global_registers(hcd->core_if);
  2827. dwc_otg_dump_host_registers(hcd->core_if);
  2828. DWC_PRINTF
  2829. ("************************************************************\n");
  2830. DWC_PRINTF("\n");
  2831. #endif
  2832. }
  2833. #ifdef DEBUG
  2834. void dwc_print_setup_data(uint8_t * setup)
  2835. {
  2836. int i;
  2837. if (CHK_DEBUG_LEVEL(DBG_HCD)) {
  2838. DWC_PRINTF("Setup Data = MSB ");
  2839. for (i = 7; i >= 0; i--)
  2840. DWC_PRINTF("%02x ", setup[i]);
  2841. DWC_PRINTF("\n");
  2842. DWC_PRINTF(" bmRequestType Tranfer = %s\n",
  2843. (setup[0] & 0x80) ? "Device-to-Host" :
  2844. "Host-to-Device");
  2845. DWC_PRINTF(" bmRequestType Type = ");
  2846. switch ((setup[0] & 0x60) >> 5) {
  2847. case 0:
  2848. DWC_PRINTF("Standard\n");
  2849. break;
  2850. case 1:
  2851. DWC_PRINTF("Class\n");
  2852. break;
  2853. case 2:
  2854. DWC_PRINTF("Vendor\n");
  2855. break;
  2856. case 3:
  2857. DWC_PRINTF("Reserved\n");
  2858. break;
  2859. }
  2860. DWC_PRINTF(" bmRequestType Recipient = ");
  2861. switch (setup[0] & 0x1f) {
  2862. case 0:
  2863. DWC_PRINTF("Device\n");
  2864. break;
  2865. case 1:
  2866. DWC_PRINTF("Interface\n");
  2867. break;
  2868. case 2:
  2869. DWC_PRINTF("Endpoint\n");
  2870. break;
  2871. case 3:
  2872. DWC_PRINTF("Other\n");
  2873. break;
  2874. default:
  2875. DWC_PRINTF("Reserved\n");
  2876. break;
  2877. }
  2878. DWC_PRINTF(" bRequest = 0x%0x\n", setup[1]);
  2879. DWC_PRINTF(" wValue = 0x%0x\n", *((uint16_t *) & setup[2]));
  2880. DWC_PRINTF(" wIndex = 0x%0x\n", *((uint16_t *) & setup[4]));
  2881. DWC_PRINTF(" wLength = 0x%0x\n\n", *((uint16_t *) & setup[6]));
  2882. }
  2883. }
  2884. #endif
  2885. void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t * hcd)
  2886. {
  2887. #if 0
  2888. DWC_PRINTF("Frame remaining at SOF:\n");
  2889. DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
  2890. hcd->frrem_samples, hcd->frrem_accum,
  2891. (hcd->frrem_samples > 0) ?
  2892. hcd->frrem_accum / hcd->frrem_samples : 0);
  2893. DWC_PRINTF("\n");
  2894. DWC_PRINTF("Frame remaining at start_transfer (uframe 7):\n");
  2895. DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
  2896. hcd->core_if->hfnum_7_samples,
  2897. hcd->core_if->hfnum_7_frrem_accum,
  2898. (hcd->core_if->hfnum_7_samples >
  2899. 0) ? hcd->core_if->hfnum_7_frrem_accum /
  2900. hcd->core_if->hfnum_7_samples : 0);
  2901. DWC_PRINTF("Frame remaining at start_transfer (uframe 0):\n");
  2902. DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
  2903. hcd->core_if->hfnum_0_samples,
  2904. hcd->core_if->hfnum_0_frrem_accum,
  2905. (hcd->core_if->hfnum_0_samples >
  2906. 0) ? hcd->core_if->hfnum_0_frrem_accum /
  2907. hcd->core_if->hfnum_0_samples : 0);
  2908. DWC_PRINTF("Frame remaining at start_transfer (uframe 1-6):\n");
  2909. DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
  2910. hcd->core_if->hfnum_other_samples,
  2911. hcd->core_if->hfnum_other_frrem_accum,
  2912. (hcd->core_if->hfnum_other_samples >
  2913. 0) ? hcd->core_if->hfnum_other_frrem_accum /
  2914. hcd->core_if->hfnum_other_samples : 0);
  2915. DWC_PRINTF("\n");
  2916. DWC_PRINTF("Frame remaining at sample point A (uframe 7):\n");
  2917. DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
  2918. hcd->hfnum_7_samples_a, hcd->hfnum_7_frrem_accum_a,
  2919. (hcd->hfnum_7_samples_a > 0) ?
  2920. hcd->hfnum_7_frrem_accum_a / hcd->hfnum_7_samples_a : 0);
  2921. DWC_PRINTF("Frame remaining at sample point A (uframe 0):\n");
  2922. DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
  2923. hcd->hfnum_0_samples_a, hcd->hfnum_0_frrem_accum_a,
  2924. (hcd->hfnum_0_samples_a > 0) ?
  2925. hcd->hfnum_0_frrem_accum_a / hcd->hfnum_0_samples_a : 0);
  2926. DWC_PRINTF("Frame remaining at sample point A (uframe 1-6):\n");
  2927. DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
  2928. hcd->hfnum_other_samples_a, hcd->hfnum_other_frrem_accum_a,
  2929. (hcd->hfnum_other_samples_a > 0) ?
  2930. hcd->hfnum_other_frrem_accum_a /
  2931. hcd->hfnum_other_samples_a : 0);
  2932. DWC_PRINTF("\n");
  2933. DWC_PRINTF("Frame remaining at sample point B (uframe 7):\n");
  2934. DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
  2935. hcd->hfnum_7_samples_b, hcd->hfnum_7_frrem_accum_b,
  2936. (hcd->hfnum_7_samples_b > 0) ?
  2937. hcd->hfnum_7_frrem_accum_b / hcd->hfnum_7_samples_b : 0);
  2938. DWC_PRINTF("Frame remaining at sample point B (uframe 0):\n");
  2939. DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
  2940. hcd->hfnum_0_samples_b, hcd->hfnum_0_frrem_accum_b,
  2941. (hcd->hfnum_0_samples_b > 0) ?
  2942. hcd->hfnum_0_frrem_accum_b / hcd->hfnum_0_samples_b : 0);
  2943. DWC_PRINTF("Frame remaining at sample point B (uframe 1-6):\n");
  2944. DWC_PRINTF(" samples %u, accum %llu, avg %llu\n",
  2945. hcd->hfnum_other_samples_b, hcd->hfnum_other_frrem_accum_b,
  2946. (hcd->hfnum_other_samples_b > 0) ?
  2947. hcd->hfnum_other_frrem_accum_b /
  2948. hcd->hfnum_other_samples_b : 0);
  2949. #endif
  2950. }
  2951. #endif /* DWC_DEVICE_ONLY */