0018-MIPS-lantiq-adds-dwc_otg.patch 528 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639
  1. From ffd7924fcc69ff146d62f131d72ef18575bf0227 Mon Sep 17 00:00:00 2001
  2. From: John Crispin <[email protected]>
  3. Date: Fri, 30 Sep 2011 14:37:36 +0200
  4. Subject: [PATCH 18/24] MIPS: lantiq: adds dwc_otg
  5. ---
  6. drivers/usb/Kconfig | 2 +
  7. drivers/usb/Makefile | 2 +
  8. drivers/usb/core/hub.c | 4 +-
  9. drivers/usb/dwc_otg/Kconfig | 37 +
  10. drivers/usb/dwc_otg/Makefile | 39 +
  11. drivers/usb/dwc_otg/dwc_otg_attr.c | 802 ++++++++
  12. drivers/usb/dwc_otg/dwc_otg_attr.h | 67 +
  13. drivers/usb/dwc_otg/dwc_otg_cil.c | 3025 +++++++++++++++++++++++++++++++
  14. drivers/usb/dwc_otg/dwc_otg_cil.h | 911 ++++++++++
  15. drivers/usb/dwc_otg/dwc_otg_cil_ifx.h | 58 +
  16. drivers/usb/dwc_otg/dwc_otg_cil_intr.c | 708 ++++++++
  17. drivers/usb/dwc_otg/dwc_otg_driver.c | 1274 +++++++++++++
  18. drivers/usb/dwc_otg/dwc_otg_driver.h | 84 +
  19. drivers/usb/dwc_otg/dwc_otg_hcd.c | 2870 +++++++++++++++++++++++++++++
  20. drivers/usb/dwc_otg/dwc_otg_hcd.h | 676 +++++++
  21. drivers/usb/dwc_otg/dwc_otg_hcd_intr.c | 1841 +++++++++++++++++++
  22. drivers/usb/dwc_otg/dwc_otg_hcd_queue.c | 794 ++++++++
  23. drivers/usb/dwc_otg/dwc_otg_ifx.c | 100 +
  24. drivers/usb/dwc_otg/dwc_otg_ifx.h | 85 +
  25. drivers/usb/dwc_otg/dwc_otg_plat.h | 269 +++
  26. drivers/usb/dwc_otg/dwc_otg_regs.h | 1797 ++++++++++++++++++
  27. 21 files changed, 15443 insertions(+), 2 deletions(-)
  28. create mode 100644 drivers/usb/dwc_otg/Kconfig
  29. create mode 100644 drivers/usb/dwc_otg/Makefile
  30. create mode 100644 drivers/usb/dwc_otg/dwc_otg_attr.c
  31. create mode 100644 drivers/usb/dwc_otg/dwc_otg_attr.h
  32. create mode 100644 drivers/usb/dwc_otg/dwc_otg_cil.c
  33. create mode 100644 drivers/usb/dwc_otg/dwc_otg_cil.h
  34. create mode 100644 drivers/usb/dwc_otg/dwc_otg_cil_ifx.h
  35. create mode 100644 drivers/usb/dwc_otg/dwc_otg_cil_intr.c
  36. create mode 100644 drivers/usb/dwc_otg/dwc_otg_driver.c
  37. create mode 100644 drivers/usb/dwc_otg/dwc_otg_driver.h
  38. create mode 100644 drivers/usb/dwc_otg/dwc_otg_hcd.c
  39. create mode 100644 drivers/usb/dwc_otg/dwc_otg_hcd.h
  40. create mode 100644 drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
  41. create mode 100644 drivers/usb/dwc_otg/dwc_otg_hcd_queue.c
  42. create mode 100644 drivers/usb/dwc_otg/dwc_otg_ifx.c
  43. create mode 100644 drivers/usb/dwc_otg/dwc_otg_ifx.h
  44. create mode 100644 drivers/usb/dwc_otg/dwc_otg_plat.h
  45. create mode 100644 drivers/usb/dwc_otg/dwc_otg_regs.h
  46. diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
  47. index 48f1781..b48c1bd 100644
  48. --- a/drivers/usb/Kconfig
  49. +++ b/drivers/usb/Kconfig
  50. @@ -116,6 +116,8 @@ source "drivers/usb/wusbcore/Kconfig"
  51. source "drivers/usb/host/Kconfig"
  52. +source "drivers/usb/dwc_otg/Kconfig"
  53. +
  54. source "drivers/usb/musb/Kconfig"
  55. source "drivers/usb/renesas_usbhs/Kconfig"
  56. diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
  57. index 30ddf8d..ba3b993 100644
  58. --- a/drivers/usb/Makefile
  59. +++ b/drivers/usb/Makefile
  60. @@ -28,6 +28,8 @@ obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
  61. obj-$(CONFIG_USB_WUSB) += wusbcore/
  62. +obj-$(CONFIG_DWC_OTG) += dwc_otg/
  63. +
  64. obj-$(CONFIG_USB_ACM) += class/
  65. obj-$(CONFIG_USB_PRINTER) += class/
  66. obj-$(CONFIG_USB_WDM) += class/
  67. diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
  68. index a428aa0..115ae9a 100644
  69. --- a/drivers/usb/core/hub.c
  70. +++ b/drivers/usb/core/hub.c
  71. @@ -2885,11 +2885,11 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
  72. udev->ttport = hdev->ttport;
  73. } else if (udev->speed != USB_SPEED_HIGH
  74. && hdev->speed == USB_SPEED_HIGH) {
  75. - if (!hub->tt.hub) {
  76. +/* if (!hub->tt.hub) {
  77. dev_err(&udev->dev, "parent hub has no TT\n");
  78. retval = -EINVAL;
  79. goto fail;
  80. - }
  81. + }*/
  82. udev->tt = &hub->tt;
  83. udev->ttport = port1;
  84. }
  85. diff --git a/drivers/usb/dwc_otg/Kconfig b/drivers/usb/dwc_otg/Kconfig
  86. new file mode 100644
  87. index 0000000..e018490
  88. --- /dev/null
  89. +++ b/drivers/usb/dwc_otg/Kconfig
  90. @@ -0,0 +1,37 @@
  91. +config DWC_OTG
  92. + tristate "Synopsis DWC_OTG support"
  93. + depends on USB
  94. + help
  95. + This driver supports Synopsis DWC_OTG IP core
  96. + embebbed on many SOCs (ralink, infineon, etc)
  97. +
  98. +choice
  99. + prompt "USB Operation Mode"
  100. + depends on DWC_OTG
  101. + default DWC_OTG_HOST_ONLY
  102. +
  103. +config DWC_OTG_HOST_ONLY
  104. + bool "HOST ONLY MODE"
  105. + depends on DWC_OTG
  106. +
  107. +#config DWC_OTG_DEVICE_ONLY
  108. +# bool "DEVICE ONLY MODE"
  109. +# depends on DWC_OTG
  110. +endchoice
  111. +
  112. +choice
  113. + prompt "Platform"
  114. + depends on DWC_OTG
  115. + default DWC_OTG_LANTIQ
  116. +
  117. +config DWC_OTG_LANTIQ
  118. + bool "Lantiq"
  119. + depends on LANTIQ
  120. + help
  121. + Danube USB Host Controller
  122. + platform support
  123. +endchoice
  124. +
  125. +config DWC_OTG_DEBUG
  126. + bool "Enable debug mode"
  127. + depends on DWC_OTG
  128. diff --git a/drivers/usb/dwc_otg/Makefile b/drivers/usb/dwc_otg/Makefile
  129. new file mode 100644
  130. index 0000000..d4d2355
  131. --- /dev/null
  132. +++ b/drivers/usb/dwc_otg/Makefile
  133. @@ -0,0 +1,39 @@
  134. +#
  135. +# Makefile for DWC_otg Highspeed USB controller driver
  136. +#
  137. +
  138. +ifeq ($(CONFIG_DWC_OTG_DEBUG),y)
  139. +EXTRA_CFLAGS += -DDEBUG
  140. +endif
  141. +
  142. +# Use one of the following flags to compile the software in host-only or
  143. +# device-only mode based on the configuration selected by the user
  144. +ifeq ($(CONFIG_DWC_OTG_HOST_ONLY),y)
  145. + EXTRA_CFLAGS += -DDWC_OTG_HOST_ONLY -DDWC_HOST_ONLY
  146. + EXTRA_CFLAGS += -DDWC_OTG_EN_ISOC -DDWC_EN_ISOC
  147. +else ifeq ($(CONFIG_DWC_OTG_DEVICE_ONLY),y)
  148. + EXTRA_CFLAGS += -DDWC_OTG_DEVICE_ONLY
  149. +else
  150. + EXTRA_CFLAGS += -DDWC_OTG_MODE
  151. +endif
  152. +
  153. +# EXTRA_CFLAGS += -DDWC_HS_ELECT_TST
  154. +# EXTRA_CFLAGS += -DDWC_OTG_EXT_CHG_PUMP
  155. +
  156. +ifeq ($(CONFIG_DWC_OTG_LANTIQ),y)
  157. + EXTRA_CFLAGS += -Dlinux -D__LINUX__ -DDWC_OTG_IFX -DDWC_OTG_HOST_ONLY -DDWC_HOST_ONLY -D__KERNEL__
  158. +endif
  159. +ifeq ($(CONFIG_DWC_OTG_LANTIQ),m)
  160. + EXTRA_CFLAGS += -Dlinux -D__LINUX__ -DDWC_OTG_IFX -DDWC_HOST_ONLY -DMODULE -D__KERNEL__ -DDEBUG
  161. +endif
  162. +
  163. +obj-$(CONFIG_DWC_OTG) := dwc_otg.o
  164. +dwc_otg-objs := dwc_otg_hcd.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o
  165. +#dwc_otg-objs += dwc_otg_pcd.o dwc_otg_pcd_intr.o
  166. +dwc_otg-objs += dwc_otg_attr.o
  167. +dwc_otg-objs += dwc_otg_cil.o dwc_otg_cil_intr.o
  168. +dwc_otg-objs += dwc_otg_ifx.o
  169. +dwc_otg-objs += dwc_otg_driver.o
  170. +
  171. +#obj-$(CONFIG_DWC_OTG_IFX) := dwc_otg_ifx.o
  172. +#dwc_otg_ifx-objs := dwc_otg_ifx.o
  173. diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.c b/drivers/usb/dwc_otg/dwc_otg_attr.c
  174. new file mode 100644
  175. index 0000000..4675a5c
  176. --- /dev/null
  177. +++ b/drivers/usb/dwc_otg/dwc_otg_attr.c
  178. @@ -0,0 +1,802 @@
  179. +/* ==========================================================================
  180. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_attr.c $
  181. + * $Revision: 1.1.1.1 $
  182. + * $Date: 2009-04-17 06:15:34 $
  183. + * $Change: 537387 $
  184. + *
  185. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  186. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  187. + * otherwise expressly agreed to in writing between Synopsys and you.
  188. + *
  189. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  190. + * any End User Software License Agreement or Agreement for Licensed Product
  191. + * with Synopsys or any supplement thereto. You are permitted to use and
  192. + * redistribute this Software in source and binary forms, with or without
  193. + * modification, provided that redistributions of source code must retain this
  194. + * notice. You may not view, use, disclose, copy or distribute this file or
  195. + * any information contained herein except pursuant to this license grant from
  196. + * Synopsys. If you do not agree with this notice, including the disclaimer
  197. + * below, then you are not authorized to use the Software.
  198. + *
  199. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  200. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  201. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  202. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  203. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  204. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  205. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  206. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  207. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  208. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  209. + * DAMAGE.
  210. + * ========================================================================== */
  211. +
  212. +/** @file
  213. + *
  214. + * The diagnostic interface will provide access to the controller for
  215. + * bringing up the hardware and testing. The Linux driver attributes
  216. + * feature will be used to provide the Linux Diagnostic
  217. + * Interface. These attributes are accessed through sysfs.
  218. + */
  219. +
  220. +/** @page "Linux Module Attributes"
  221. + *
  222. + * The Linux module attributes feature is used to provide the Linux
  223. + * Diagnostic Interface. These attributes are accessed through sysfs.
  224. + * The diagnostic interface will provide access to the controller for
  225. + * bringing up the hardware and testing.
  226. +
  227. +
  228. + The following table shows the attributes.
  229. + <table>
  230. + <tr>
  231. + <td><b> Name</b></td>
  232. + <td><b> Description</b></td>
  233. + <td><b> Access</b></td>
  234. + </tr>
  235. +
  236. + <tr>
  237. + <td> mode </td>
  238. + <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
  239. + <td> Read</td>
  240. + </tr>
  241. +
  242. + <tr>
  243. + <td> hnpcapable </td>
  244. + <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
  245. + Read returns the current value.</td>
  246. + <td> Read/Write</td>
  247. + </tr>
  248. +
  249. + <tr>
  250. + <td> srpcapable </td>
  251. + <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
  252. + Read returns the current value.</td>
  253. + <td> Read/Write</td>
  254. + </tr>
  255. +
  256. + <tr>
  257. + <td> hnp </td>
  258. + <td> Initiates the Host Negotiation Protocol. Read returns the status.</td>
  259. + <td> Read/Write</td>
  260. + </tr>
  261. +
  262. + <tr>
  263. + <td> srp </td>
  264. + <td> Initiates the Session Request Protocol. Read returns the status.</td>
  265. + <td> Read/Write</td>
  266. + </tr>
  267. +
  268. + <tr>
  269. + <td> buspower </td>
  270. + <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
  271. + <td> Read/Write</td>
  272. + </tr>
  273. +
  274. + <tr>
  275. + <td> bussuspend </td>
  276. + <td> Suspends the USB bus.</td>
  277. + <td> Read/Write</td>
  278. + </tr>
  279. +
  280. + <tr>
  281. + <td> busconnected </td>
  282. + <td> Gets the connection status of the bus</td>
  283. + <td> Read</td>
  284. + </tr>
  285. +
  286. + <tr>
  287. + <td> gotgctl </td>
  288. + <td> Gets or sets the Core Control Status Register.</td>
  289. + <td> Read/Write</td>
  290. + </tr>
  291. +
  292. + <tr>
  293. + <td> gusbcfg </td>
  294. + <td> Gets or sets the Core USB Configuration Register</td>
  295. + <td> Read/Write</td>
  296. + </tr>
  297. +
  298. + <tr>
  299. + <td> grxfsiz </td>
  300. + <td> Gets or sets the Receive FIFO Size Register</td>
  301. + <td> Read/Write</td>
  302. + </tr>
  303. +
  304. + <tr>
  305. + <td> gnptxfsiz </td>
  306. + <td> Gets or sets the non-periodic Transmit Size Register</td>
  307. + <td> Read/Write</td>
  308. + </tr>
  309. +
  310. + <tr>
  311. + <td> gpvndctl </td>
  312. + <td> Gets or sets the PHY Vendor Control Register</td>
  313. + <td> Read/Write</td>
  314. + </tr>
  315. +
  316. + <tr>
  317. + <td> ggpio </td>
  318. + <td> Gets the value in the lower 16-bits of the General Purpose IO Register
  319. + or sets the upper 16 bits.</td>
  320. + <td> Read/Write</td>
  321. + </tr>
  322. +
  323. + <tr>
  324. + <td> guid </td>
  325. + <td> Gets or sets the value of the User ID Register</td>
  326. + <td> Read/Write</td>
  327. + </tr>
  328. +
  329. + <tr>
  330. + <td> gsnpsid </td>
  331. + <td> Gets the value of the Synopsys ID Regester</td>
  332. + <td> Read</td>
  333. + </tr>
  334. +
  335. + <tr>
  336. + <td> devspeed </td>
  337. + <td> Gets or sets the device speed setting in the DCFG register</td>
  338. + <td> Read/Write</td>
  339. + </tr>
  340. +
  341. + <tr>
  342. + <td> enumspeed </td>
  343. + <td> Gets the device enumeration Speed.</td>
  344. + <td> Read</td>
  345. + </tr>
  346. +
  347. + <tr>
  348. + <td> hptxfsiz </td>
  349. + <td> Gets the value of the Host Periodic Transmit FIFO</td>
  350. + <td> Read</td>
  351. + </tr>
  352. +
  353. + <tr>
  354. + <td> hprt0 </td>
  355. + <td> Gets or sets the value in the Host Port Control and Status Register</td>
  356. + <td> Read/Write</td>
  357. + </tr>
  358. +
  359. + <tr>
  360. + <td> regoffset </td>
  361. + <td> Sets the register offset for the next Register Access</td>
  362. + <td> Read/Write</td>
  363. + </tr>
  364. +
  365. + <tr>
  366. + <td> regvalue </td>
  367. + <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
  368. + <td> Read/Write</td>
  369. + </tr>
  370. +
  371. + <tr>
  372. + <td> remote_wakeup </td>
  373. + <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
  374. + wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
  375. + Wakeup signalling bit in the Device Control Register is set for 1
  376. + milli-second.</td>
  377. + <td> Read/Write</td>
  378. + </tr>
  379. +
  380. + <tr>
  381. + <td> regdump </td>
  382. + <td> Dumps the contents of core registers.</td>
  383. + <td> Read</td>
  384. + </tr>
  385. +
  386. + <tr>
  387. + <td> hcddump </td>
  388. + <td> Dumps the current HCD state.</td>
  389. + <td> Read</td>
  390. + </tr>
  391. +
  392. + <tr>
  393. + <td> hcd_frrem </td>
  394. + <td> Shows the average value of the Frame Remaining
  395. + field in the Host Frame Number/Frame Remaining register when an SOF interrupt
  396. + occurs. This can be used to determine the average interrupt latency. Also
  397. + shows the average Frame Remaining value for start_transfer and the "a" and
  398. + "b" sample points. The "a" and "b" sample points may be used during debugging
  399. + bto determine how long it takes to execute a section of the HCD code.</td>
  400. + <td> Read</td>
  401. + </tr>
  402. +
  403. + <tr>
  404. + <td> rd_reg_test </td>
  405. + <td> Displays the time required to read the GNPTXFSIZ register many times
  406. + (the output shows the number of times the register is read).
  407. + <td> Read</td>
  408. + </tr>
  409. +
  410. + <tr>
  411. + <td> wr_reg_test </td>
  412. + <td> Displays the time required to write the GNPTXFSIZ register many times
  413. + (the output shows the number of times the register is written).
  414. + <td> Read</td>
  415. + </tr>
  416. +
  417. + </table>
  418. +
  419. + Example usage:
  420. + To get the current mode:
  421. + cat /sys/devices/lm0/mode
  422. +
  423. + To power down the USB:
  424. + echo 0 > /sys/devices/lm0/buspower
  425. + */
  426. +#include <linux/kernel.h>
  427. +#include <linux/module.h>
  428. +#include <linux/moduleparam.h>
  429. +#include <linux/init.h>
  430. +#include <linux/device.h>
  431. +#include <linux/errno.h>
  432. +#include <linux/types.h>
  433. +#include <linux/stat.h> /* permission constants */
  434. +
  435. +#include <asm/io.h>
  436. +
  437. +#include "dwc_otg_plat.h"
  438. +#include "dwc_otg_attr.h"
  439. +#include "dwc_otg_driver.h"
  440. +// #include "dwc_otg_pcd.h"
  441. +#include "dwc_otg_hcd.h"
  442. +
  443. +// 20070316, winder added.
  444. +#ifndef SZ_256K
  445. +#define SZ_256K 0x00040000
  446. +#endif
  447. +
  448. +/*
  449. + * MACROs for defining sysfs attribute
  450. + */
  451. +#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
  452. +static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
  453. +{ \
  454. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
  455. + uint32_t val; \
  456. + val = dwc_read_reg32 (_addr_); \
  457. + val = (val & (_mask_)) >> _shift_; \
  458. + return sprintf (buf, "%s = 0x%x\n", _string_, val); \
  459. +}
  460. +#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
  461. +static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \
  462. +{ \
  463. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
  464. + uint32_t set = simple_strtoul(buf, NULL, 16); \
  465. + uint32_t clear = set; \
  466. + clear = ((~clear) << _shift_) & _mask_; \
  467. + set = (set << _shift_) & _mask_; \
  468. + dev_dbg(_dev, "Storing Address=0x%08x Set=0x%08x Clear=0x%08x\n", (uint32_t)_addr_, set, clear); \
  469. + dwc_modify_reg32(_addr_, clear, set); \
  470. + return count; \
  471. +}
  472. +
  473. +#define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
  474. +DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
  475. +DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
  476. +DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
  477. +
  478. +#define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
  479. +DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_addr_,_mask_,_shift_,_string_) \
  480. +DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
  481. +
  482. +/*
  483. + * MACROs for defining sysfs attribute for 32-bit registers
  484. + */
  485. +#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
  486. +static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
  487. +{ \
  488. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
  489. + uint32_t val; \
  490. + val = dwc_read_reg32 (_addr_); \
  491. + return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
  492. +}
  493. +#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
  494. +static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, const char *buf, size_t count) \
  495. +{ \
  496. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);\
  497. + uint32_t val = simple_strtoul(buf, NULL, 16); \
  498. + dev_dbg(_dev, "Storing Address=0x%08x Val=0x%08x\n", (uint32_t)_addr_, val); \
  499. + dwc_write_reg32(_addr_, val); \
  500. + return count; \
  501. +}
  502. +
  503. +#define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
  504. +DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
  505. +DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_addr_,_string_) \
  506. +DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
  507. +
  508. +#define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
  509. +DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_addr_,_string_) \
  510. +DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
  511. +
  512. +
  513. +/** @name Functions for Show/Store of Attributes */
  514. +/**@{*/
  515. +
  516. +/**
  517. + * Show the register offset of the Register Access.
  518. + */
  519. +static ssize_t regoffset_show( struct device *_dev, struct device_attribute *attr, char *buf)
  520. +{
  521. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  522. + return snprintf(buf, sizeof("0xFFFFFFFF\n")+1,"0x%08x\n", otg_dev->reg_offset);
  523. +}
  524. +
  525. +/**
  526. + * Set the register offset for the next Register Access Read/Write
  527. + */
  528. +static ssize_t regoffset_store( struct device *_dev, struct device_attribute *attr, const char *buf,
  529. + size_t count )
  530. +{
  531. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  532. + uint32_t offset = simple_strtoul(buf, NULL, 16);
  533. + //dev_dbg(_dev, "Offset=0x%08x\n", offset);
  534. + if (offset < SZ_256K ) {
  535. + otg_dev->reg_offset = offset;
  536. + }
  537. + else {
  538. + dev_err( _dev, "invalid offset\n" );
  539. + }
  540. +
  541. + return count;
  542. +}
  543. +DEVICE_ATTR(regoffset, S_IRUGO|S_IWUSR, regoffset_show, regoffset_store);
  544. +
  545. +/**
  546. + * Show the value of the register at the offset in the reg_offset
  547. + * attribute.
  548. + */
  549. +static ssize_t regvalue_show( struct device *_dev, struct device_attribute *attr, char *buf)
  550. +{
  551. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  552. + uint32_t val;
  553. + volatile uint32_t *addr;
  554. +
  555. + if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
  556. + /* Calculate the address */
  557. + addr = (uint32_t*)(otg_dev->reg_offset +
  558. + (uint8_t*)otg_dev->base);
  559. + //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
  560. + val = dwc_read_reg32( addr );
  561. + return snprintf(buf, sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n")+1,
  562. + "Reg@0x%06x = 0x%08x\n",
  563. + otg_dev->reg_offset, val);
  564. + }
  565. + else {
  566. + dev_err(_dev, "Invalid offset (0x%0x)\n",
  567. + otg_dev->reg_offset);
  568. + return sprintf(buf, "invalid offset\n" );
  569. + }
  570. +}
  571. +
  572. +/**
  573. + * Store the value in the register at the offset in the reg_offset
  574. + * attribute.
  575. + *
  576. + */
  577. +static ssize_t regvalue_store( struct device *_dev, struct device_attribute *attr, const char *buf,
  578. + size_t count )
  579. +{
  580. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  581. + volatile uint32_t * addr;
  582. + uint32_t val = simple_strtoul(buf, NULL, 16);
  583. + //dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
  584. + if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) {
  585. + /* Calculate the address */
  586. + addr = (uint32_t*)(otg_dev->reg_offset +
  587. + (uint8_t*)otg_dev->base);
  588. + //dev_dbg(_dev, "@0x%08x\n", (unsigned)addr);
  589. + dwc_write_reg32( addr, val );
  590. + }
  591. + else {
  592. + dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
  593. + otg_dev->reg_offset);
  594. + }
  595. + return count;
  596. +}
  597. +DEVICE_ATTR(regvalue, S_IRUGO|S_IWUSR, regvalue_show, regvalue_store);
  598. +
  599. +/*
  600. + * Attributes
  601. + */
  602. +DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<20),20,"Mode");
  603. +DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<9),9,"Mode");
  604. +DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable,&(otg_dev->core_if->core_global_regs->gusbcfg),(1<<8),8,"Mode");
  605. +
  606. +//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
  607. +//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
  608. +DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected,otg_dev->core_if->host_if->hprt0,0x01,0,"Bus Connected");
  609. +
  610. +DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl,&(otg_dev->core_if->core_global_regs->gotgctl),"GOTGCTL");
  611. +DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,&(otg_dev->core_if->core_global_regs->gusbcfg),"GUSBCFG");
  612. +DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,&(otg_dev->core_if->core_global_regs->grxfsiz),"GRXFSIZ");
  613. +DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,&(otg_dev->core_if->core_global_regs->gnptxfsiz),"GNPTXFSIZ");
  614. +DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,&(otg_dev->core_if->core_global_regs->gpvndctl),"GPVNDCTL");
  615. +DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,&(otg_dev->core_if->core_global_regs->ggpio),"GGPIO");
  616. +DWC_OTG_DEVICE_ATTR_REG32_RW(guid,&(otg_dev->core_if->core_global_regs->guid),"GUID");
  617. +DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,&(otg_dev->core_if->core_global_regs->gsnpsid),"GSNPSID");
  618. +DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dcfg),0x3,0,"Device Speed");
  619. +DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed,&(otg_dev->core_if->dev_if->dev_global_regs->dsts),0x6,1,"Device Enumeration Speed");
  620. +
  621. +DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,&(otg_dev->core_if->core_global_regs->hptxfsiz),"HPTXFSIZ");
  622. +DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0,otg_dev->core_if->host_if->hprt0,"HPRT0");
  623. +
  624. +
  625. +/**
  626. + * @todo Add code to initiate the HNP.
  627. + */
  628. +/**
  629. + * Show the HNP status bit
  630. + */
  631. +static ssize_t hnp_show( struct device *_dev, struct device_attribute *attr, char *buf)
  632. +{
  633. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  634. + gotgctl_data_t val;
  635. + val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
  636. + return sprintf (buf, "HstNegScs = 0x%x\n", val.b.hstnegscs);
  637. +}
  638. +
  639. +/**
  640. + * Set the HNP Request bit
  641. + */
  642. +static ssize_t hnp_store( struct device *_dev, struct device_attribute *attr, const char *buf,
  643. + size_t count )
  644. +{
  645. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  646. + uint32_t in = simple_strtoul(buf, NULL, 16);
  647. + uint32_t *addr = (uint32_t *)&(otg_dev->core_if->core_global_regs->gotgctl);
  648. + gotgctl_data_t mem;
  649. + mem.d32 = dwc_read_reg32(addr);
  650. + mem.b.hnpreq = in;
  651. + dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
  652. + dwc_write_reg32(addr, mem.d32);
  653. + return count;
  654. +}
  655. +DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
  656. +
  657. +/**
  658. + * @todo Add code to initiate the SRP.
  659. + */
  660. +/**
  661. + * Show the SRP status bit
  662. + */
  663. +static ssize_t srp_show( struct device *_dev, struct device_attribute *attr, char *buf)
  664. +{
  665. +#ifndef DWC_HOST_ONLY
  666. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  667. + gotgctl_data_t val;
  668. + val.d32 = dwc_read_reg32 (&(otg_dev->core_if->core_global_regs->gotgctl));
  669. + return sprintf (buf, "SesReqScs = 0x%x\n", val.b.sesreqscs);
  670. +#else
  671. + return sprintf(buf, "Host Only Mode!\n");
  672. +#endif
  673. +}
  674. +
  675. +/**
  676. + * Set the SRP Request bit
  677. + */
  678. +static ssize_t srp_store( struct device *_dev, struct device_attribute *attr, const char *buf,
  679. + size_t count )
  680. +{
  681. +#ifndef DWC_HOST_ONLY
  682. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  683. + dwc_otg_pcd_initiate_srp(otg_dev->pcd);
  684. +#endif
  685. + return count;
  686. +}
  687. +DEVICE_ATTR(srp, 0644, srp_show, srp_store);
  688. +
  689. +/**
  690. + * @todo Need to do more for power on/off?
  691. + */
  692. +/**
  693. + * Show the Bus Power status
  694. + */
  695. +static ssize_t buspower_show( struct device *_dev, struct device_attribute *attr, char *buf)
  696. +{
  697. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  698. + hprt0_data_t val;
  699. + val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
  700. + return sprintf (buf, "Bus Power = 0x%x\n", val.b.prtpwr);
  701. +}
  702. +
  703. +
  704. +/**
  705. + * Set the Bus Power status
  706. + */
  707. +static ssize_t buspower_store( struct device *_dev, struct device_attribute *attr, const char *buf,
  708. + size_t count )
  709. +{
  710. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  711. + uint32_t on = simple_strtoul(buf, NULL, 16);
  712. + uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
  713. + hprt0_data_t mem;
  714. +
  715. + mem.d32 = dwc_read_reg32(addr);
  716. + mem.b.prtpwr = on;
  717. +
  718. + //dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
  719. + dwc_write_reg32(addr, mem.d32);
  720. +
  721. + return count;
  722. +}
  723. +DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
  724. +
  725. +/**
  726. + * @todo Need to do more for suspend?
  727. + */
  728. +/**
  729. + * Show the Bus Suspend status
  730. + */
  731. +static ssize_t bussuspend_show( struct device *_dev, struct device_attribute *attr, char *buf)
  732. +{
  733. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  734. + hprt0_data_t val;
  735. + val.d32 = dwc_read_reg32 (otg_dev->core_if->host_if->hprt0);
  736. + return sprintf (buf, "Bus Suspend = 0x%x\n", val.b.prtsusp);
  737. +}
  738. +
  739. +/**
  740. + * Set the Bus Suspend status
  741. + */
  742. +static ssize_t bussuspend_store( struct device *_dev, struct device_attribute *attr, const char *buf,
  743. + size_t count )
  744. +{
  745. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  746. + uint32_t in = simple_strtoul(buf, NULL, 16);
  747. + uint32_t *addr = (uint32_t *)otg_dev->core_if->host_if->hprt0;
  748. + hprt0_data_t mem;
  749. + mem.d32 = dwc_read_reg32(addr);
  750. + mem.b.prtsusp = in;
  751. + dev_dbg(_dev, "Storing Address=0x%08x Data=0x%08x\n", (uint32_t)addr, mem.d32);
  752. + dwc_write_reg32(addr, mem.d32);
  753. + return count;
  754. +}
  755. +DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
  756. +
  757. +/**
  758. + * Show the status of Remote Wakeup.
  759. + */
  760. +static ssize_t remote_wakeup_show( struct device *_dev, struct device_attribute *attr, char *buf)
  761. +{
  762. +#ifndef DWC_HOST_ONLY
  763. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  764. + dctl_data_t val;
  765. + val.d32 = dwc_read_reg32( &otg_dev->core_if->dev_if->dev_global_regs->dctl);
  766. + return sprintf( buf, "Remote Wakeup = %d Enabled = %d\n",
  767. + val.b.rmtwkupsig, otg_dev->pcd->remote_wakeup_enable);
  768. +#else
  769. + return sprintf(buf, "Host Only Mode!\n");
  770. +#endif
  771. +}
  772. +
  773. +/**
  774. + * Initiate a remote wakeup of the host. The Device control register
  775. + * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
  776. + * flag is set.
  777. + *
  778. + */
  779. +static ssize_t remote_wakeup_store( struct device *_dev, struct device_attribute *attr, const char *buf,
  780. + size_t count )
  781. +{
  782. +#ifndef DWC_HOST_ONLY
  783. + uint32_t val = simple_strtoul(buf, NULL, 16);
  784. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  785. + if (val&1) {
  786. + dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
  787. + }
  788. + else {
  789. + dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
  790. + }
  791. +#endif
  792. + return count;
  793. +}
  794. +DEVICE_ATTR(remote_wakeup, S_IRUGO|S_IWUSR, remote_wakeup_show,
  795. + remote_wakeup_store);
  796. +
  797. +/**
  798. + * Dump global registers and either host or device registers (depending on the
  799. + * current mode of the core).
  800. + */
  801. +static ssize_t regdump_show( struct device *_dev, struct device_attribute *attr, char *buf)
  802. +{
  803. +#ifdef DEBUG
  804. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  805. + printk("%s otg_dev=0x%p\n", __FUNCTION__, otg_dev);
  806. +
  807. + dwc_otg_dump_global_registers( otg_dev->core_if);
  808. + if (dwc_otg_is_host_mode(otg_dev->core_if)) {
  809. + dwc_otg_dump_host_registers( otg_dev->core_if);
  810. + } else {
  811. + dwc_otg_dump_dev_registers( otg_dev->core_if);
  812. + }
  813. +#endif
  814. +
  815. + return sprintf( buf, "Register Dump\n" );
  816. +}
  817. +
  818. +DEVICE_ATTR(regdump, S_IRUGO|S_IWUSR, regdump_show, 0);
  819. +
  820. +/**
  821. + * Dump the current hcd state.
  822. + */
  823. +static ssize_t hcddump_show( struct device *_dev, struct device_attribute *attr, char *buf)
  824. +{
  825. +#ifndef DWC_DEVICE_ONLY
  826. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  827. + dwc_otg_hcd_dump_state(otg_dev->hcd);
  828. +#endif
  829. + return sprintf( buf, "HCD Dump\n" );
  830. +}
  831. +
  832. +DEVICE_ATTR(hcddump, S_IRUGO|S_IWUSR, hcddump_show, 0);
  833. +
  834. +/**
  835. + * Dump the average frame remaining at SOF. This can be used to
  836. + * determine average interrupt latency. Frame remaining is also shown for
  837. + * start transfer and two additional sample points.
  838. + */
  839. +static ssize_t hcd_frrem_show( struct device *_dev, struct device_attribute *attr, char *buf)
  840. +{
  841. +#ifndef DWC_DEVICE_ONLY
  842. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  843. + dwc_otg_hcd_dump_frrem(otg_dev->hcd);
  844. +#endif
  845. + return sprintf( buf, "HCD Dump Frame Remaining\n" );
  846. +}
  847. +
  848. +DEVICE_ATTR(hcd_frrem, S_IRUGO|S_IWUSR, hcd_frrem_show, 0);
  849. +
  850. +/**
  851. + * Displays the time required to read the GNPTXFSIZ register many times (the
  852. + * output shows the number of times the register is read).
  853. + */
  854. +#define RW_REG_COUNT 10000000
  855. +#define MSEC_PER_JIFFIE 1000/HZ
  856. +static ssize_t rd_reg_test_show( struct device *_dev, struct device_attribute *attr, char *buf)
  857. +{
  858. + int i;
  859. + int time;
  860. + int start_jiffies;
  861. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  862. +
  863. + printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
  864. + HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
  865. + start_jiffies = jiffies;
  866. + for (i = 0; i < RW_REG_COUNT; i++) {
  867. + dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
  868. + }
  869. + time = jiffies - start_jiffies;
  870. + return sprintf( buf, "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
  871. + RW_REG_COUNT, time * MSEC_PER_JIFFIE, time );
  872. +}
  873. +
  874. +DEVICE_ATTR(rd_reg_test, S_IRUGO|S_IWUSR, rd_reg_test_show, 0);
  875. +
  876. +/**
  877. + * Displays the time required to write the GNPTXFSIZ register many times (the
  878. + * output shows the number of times the register is written).
  879. + */
  880. +static ssize_t wr_reg_test_show( struct device *_dev, struct device_attribute *attr, char *buf)
  881. +{
  882. + int i;
  883. + int time;
  884. + int start_jiffies;
  885. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  886. + uint32_t reg_val;
  887. +
  888. + printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
  889. + HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
  890. + reg_val = dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz);
  891. + start_jiffies = jiffies;
  892. + for (i = 0; i < RW_REG_COUNT; i++) {
  893. + dwc_write_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz, reg_val);
  894. + }
  895. + time = jiffies - start_jiffies;
  896. + return sprintf( buf, "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
  897. + RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
  898. +}
  899. +
  900. +DEVICE_ATTR(wr_reg_test, S_IRUGO|S_IWUSR, wr_reg_test_show, 0);
  901. +/**@}*/
  902. +
  903. +/**
  904. + * Create the device files
  905. + */
  906. +void dwc_otg_attr_create (struct device *_dev)
  907. +{
  908. + int retval;
  909. +
  910. + retval = device_create_file(_dev, &dev_attr_regoffset);
  911. + retval += device_create_file(_dev, &dev_attr_regvalue);
  912. + retval += device_create_file(_dev, &dev_attr_mode);
  913. + retval += device_create_file(_dev, &dev_attr_hnpcapable);
  914. + retval += device_create_file(_dev, &dev_attr_srpcapable);
  915. + retval += device_create_file(_dev, &dev_attr_hnp);
  916. + retval += device_create_file(_dev, &dev_attr_srp);
  917. + retval += device_create_file(_dev, &dev_attr_buspower);
  918. + retval += device_create_file(_dev, &dev_attr_bussuspend);
  919. + retval += device_create_file(_dev, &dev_attr_busconnected);
  920. + retval += device_create_file(_dev, &dev_attr_gotgctl);
  921. + retval += device_create_file(_dev, &dev_attr_gusbcfg);
  922. + retval += device_create_file(_dev, &dev_attr_grxfsiz);
  923. + retval += device_create_file(_dev, &dev_attr_gnptxfsiz);
  924. + retval += device_create_file(_dev, &dev_attr_gpvndctl);
  925. + retval += device_create_file(_dev, &dev_attr_ggpio);
  926. + retval += device_create_file(_dev, &dev_attr_guid);
  927. + retval += device_create_file(_dev, &dev_attr_gsnpsid);
  928. + retval += device_create_file(_dev, &dev_attr_devspeed);
  929. + retval += device_create_file(_dev, &dev_attr_enumspeed);
  930. + retval += device_create_file(_dev, &dev_attr_hptxfsiz);
  931. + retval += device_create_file(_dev, &dev_attr_hprt0);
  932. + retval += device_create_file(_dev, &dev_attr_remote_wakeup);
  933. + retval += device_create_file(_dev, &dev_attr_regdump);
  934. + retval += device_create_file(_dev, &dev_attr_hcddump);
  935. + retval += device_create_file(_dev, &dev_attr_hcd_frrem);
  936. + retval += device_create_file(_dev, &dev_attr_rd_reg_test);
  937. + retval += device_create_file(_dev, &dev_attr_wr_reg_test);
  938. +
  939. + if(retval != 0)
  940. + {
  941. + DWC_PRINT("cannot create sysfs device files.\n");
  942. + // DWC_PRINT("killing own sysfs device files!\n");
  943. + dwc_otg_attr_remove(_dev);
  944. + }
  945. +}
  946. +
  947. +/**
  948. + * Remove the device files
  949. + */
  950. +void dwc_otg_attr_remove (struct device *_dev)
  951. +{
  952. + device_remove_file(_dev, &dev_attr_regoffset);
  953. + device_remove_file(_dev, &dev_attr_regvalue);
  954. + device_remove_file(_dev, &dev_attr_mode);
  955. + device_remove_file(_dev, &dev_attr_hnpcapable);
  956. + device_remove_file(_dev, &dev_attr_srpcapable);
  957. + device_remove_file(_dev, &dev_attr_hnp);
  958. + device_remove_file(_dev, &dev_attr_srp);
  959. + device_remove_file(_dev, &dev_attr_buspower);
  960. + device_remove_file(_dev, &dev_attr_bussuspend);
  961. + device_remove_file(_dev, &dev_attr_busconnected);
  962. + device_remove_file(_dev, &dev_attr_gotgctl);
  963. + device_remove_file(_dev, &dev_attr_gusbcfg);
  964. + device_remove_file(_dev, &dev_attr_grxfsiz);
  965. + device_remove_file(_dev, &dev_attr_gnptxfsiz);
  966. + device_remove_file(_dev, &dev_attr_gpvndctl);
  967. + device_remove_file(_dev, &dev_attr_ggpio);
  968. + device_remove_file(_dev, &dev_attr_guid);
  969. + device_remove_file(_dev, &dev_attr_gsnpsid);
  970. + device_remove_file(_dev, &dev_attr_devspeed);
  971. + device_remove_file(_dev, &dev_attr_enumspeed);
  972. + device_remove_file(_dev, &dev_attr_hptxfsiz);
  973. + device_remove_file(_dev, &dev_attr_hprt0);
  974. + device_remove_file(_dev, &dev_attr_remote_wakeup);
  975. + device_remove_file(_dev, &dev_attr_regdump);
  976. + device_remove_file(_dev, &dev_attr_hcddump);
  977. + device_remove_file(_dev, &dev_attr_hcd_frrem);
  978. + device_remove_file(_dev, &dev_attr_rd_reg_test);
  979. + device_remove_file(_dev, &dev_attr_wr_reg_test);
  980. +}
  981. diff --git a/drivers/usb/dwc_otg/dwc_otg_attr.h b/drivers/usb/dwc_otg/dwc_otg_attr.h
  982. new file mode 100644
  983. index 0000000..4bbf7df
  984. --- /dev/null
  985. +++ b/drivers/usb/dwc_otg/dwc_otg_attr.h
  986. @@ -0,0 +1,67 @@
  987. +/* ==========================================================================
  988. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_attr.h $
  989. + * $Revision: 1.1.1.1 $
  990. + * $Date: 2009-04-17 06:15:34 $
  991. + * $Change: 510275 $
  992. + *
  993. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  994. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  995. + * otherwise expressly agreed to in writing between Synopsys and you.
  996. + *
  997. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  998. + * any End User Software License Agreement or Agreement for Licensed Product
  999. + * with Synopsys or any supplement thereto. You are permitted to use and
  1000. + * redistribute this Software in source and binary forms, with or without
  1001. + * modification, provided that redistributions of source code must retain this
  1002. + * notice. You may not view, use, disclose, copy or distribute this file or
  1003. + * any information contained herein except pursuant to this license grant from
  1004. + * Synopsys. If you do not agree with this notice, including the disclaimer
  1005. + * below, then you are not authorized to use the Software.
  1006. + *
  1007. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  1008. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1009. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1010. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  1011. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  1012. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  1013. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1014. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1015. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1016. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  1017. + * DAMAGE.
  1018. + * ========================================================================== */
  1019. +
  1020. +#if !defined(__DWC_OTG_ATTR_H__)
  1021. +#define __DWC_OTG_ATTR_H__
  1022. +
  1023. +/** @file
  1024. + * This file contains the interface to the Linux device attributes.
  1025. + */
  1026. +extern struct device_attribute dev_attr_regoffset;
  1027. +extern struct device_attribute dev_attr_regvalue;
  1028. +
  1029. +extern struct device_attribute dev_attr_mode;
  1030. +extern struct device_attribute dev_attr_hnpcapable;
  1031. +extern struct device_attribute dev_attr_srpcapable;
  1032. +extern struct device_attribute dev_attr_hnp;
  1033. +extern struct device_attribute dev_attr_srp;
  1034. +extern struct device_attribute dev_attr_buspower;
  1035. +extern struct device_attribute dev_attr_bussuspend;
  1036. +extern struct device_attribute dev_attr_busconnected;
  1037. +extern struct device_attribute dev_attr_gotgctl;
  1038. +extern struct device_attribute dev_attr_gusbcfg;
  1039. +extern struct device_attribute dev_attr_grxfsiz;
  1040. +extern struct device_attribute dev_attr_gnptxfsiz;
  1041. +extern struct device_attribute dev_attr_gpvndctl;
  1042. +extern struct device_attribute dev_attr_ggpio;
  1043. +extern struct device_attribute dev_attr_guid;
  1044. +extern struct device_attribute dev_attr_gsnpsid;
  1045. +extern struct device_attribute dev_attr_devspeed;
  1046. +extern struct device_attribute dev_attr_enumspeed;
  1047. +extern struct device_attribute dev_attr_hptxfsiz;
  1048. +extern struct device_attribute dev_attr_hprt0;
  1049. +
  1050. +void dwc_otg_attr_create (struct device *_dev);
  1051. +void dwc_otg_attr_remove (struct device *_dev);
  1052. +
  1053. +#endif
  1054. diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c
  1055. new file mode 100644
  1056. index 0000000..42c69eb
  1057. --- /dev/null
  1058. +++ b/drivers/usb/dwc_otg/dwc_otg_cil.c
  1059. @@ -0,0 +1,3025 @@
  1060. +/* ==========================================================================
  1061. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_cil.c $
  1062. + * $Revision: 1.1.1.1 $
  1063. + * $Date: 2009-04-17 06:15:34 $
  1064. + * $Change: 631780 $
  1065. + *
  1066. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  1067. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  1068. + * otherwise expressly agreed to in writing between Synopsys and you.
  1069. + *
  1070. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  1071. + * any End User Software License Agreement or Agreement for Licensed Product
  1072. + * with Synopsys or any supplement thereto. You are permitted to use and
  1073. + * redistribute this Software in source and binary forms, with or without
  1074. + * modification, provided that redistributions of source code must retain this
  1075. + * notice. You may not view, use, disclose, copy or distribute this file or
  1076. + * any information contained herein except pursuant to this license grant from
  1077. + * Synopsys. If you do not agree with this notice, including the disclaimer
  1078. + * below, then you are not authorized to use the Software.
  1079. + *
  1080. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  1081. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1082. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1083. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  1084. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  1085. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  1086. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1087. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1088. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1089. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  1090. + * DAMAGE.
  1091. + * ========================================================================== */
  1092. +
  1093. +/** @file
  1094. + *
  1095. + * The Core Interface Layer provides basic services for accessing and
  1096. + * managing the DWC_otg hardware. These services are used by both the
  1097. + * Host Controller Driver and the Peripheral Controller Driver.
  1098. + *
  1099. + * The CIL manages the memory map for the core so that the HCD and PCD
  1100. + * don't have to do this separately. It also handles basic tasks like
  1101. + * reading/writing the registers and data FIFOs in the controller.
  1102. + * Some of the data access functions provide encapsulation of several
  1103. + * operations required to perform a task, such as writing multiple
  1104. + * registers to start a transfer. Finally, the CIL performs basic
  1105. + * services that are not specific to either the host or device modes
  1106. + * of operation. These services include management of the OTG Host
  1107. + * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
  1108. + * Diagnostic API is also provided to allow testing of the controller
  1109. + * hardware.
  1110. + *
  1111. + * The Core Interface Layer has the following requirements:
  1112. + * - Provides basic controller operations.
  1113. + * - Minimal use of OS services.
  1114. + * - The OS services used will be abstracted by using inline functions
  1115. + * or macros.
  1116. + *
  1117. + */
  1118. +#include <asm/unaligned.h>
  1119. +
  1120. +#ifdef DEBUG
  1121. +#include <linux/jiffies.h>
  1122. +#endif
  1123. +
  1124. +#include "dwc_otg_plat.h"
  1125. +
  1126. +#include "dwc_otg_regs.h"
  1127. +#include "dwc_otg_cil.h"
  1128. +
  1129. +/**
  1130. + * This function is called to initialize the DWC_otg CSR data
  1131. + * structures. The register addresses in the device and host
  1132. + * structures are initialized from the base address supplied by the
  1133. + * caller. The calling function must make the OS calls to get the
  1134. + * base address of the DWC_otg controller registers. The core_params
  1135. + * argument holds the parameters that specify how the core should be
  1136. + * configured.
  1137. + *
  1138. + * @param[in] _reg_base_addr Base address of DWC_otg core registers
  1139. + * @param[in] _core_params Pointer to the core configuration parameters
  1140. + *
  1141. + */
  1142. +dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *_reg_base_addr,
  1143. + dwc_otg_core_params_t *_core_params)
  1144. +{
  1145. + dwc_otg_core_if_t *core_if = 0;
  1146. + dwc_otg_dev_if_t *dev_if = 0;
  1147. + dwc_otg_host_if_t *host_if = 0;
  1148. + uint8_t *reg_base = (uint8_t *)_reg_base_addr;
  1149. + int i = 0;
  1150. +
  1151. + DWC_DEBUGPL(DBG_CILV, "%s(%p,%p)\n", __func__, _reg_base_addr, _core_params);
  1152. +
  1153. + core_if = kmalloc( sizeof(dwc_otg_core_if_t), GFP_KERNEL);
  1154. + if (core_if == 0) {
  1155. + DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_core_if_t failed\n");
  1156. + return 0;
  1157. + }
  1158. + memset(core_if, 0, sizeof(dwc_otg_core_if_t));
  1159. +
  1160. + core_if->core_params = _core_params;
  1161. + core_if->core_global_regs = (dwc_otg_core_global_regs_t *)reg_base;
  1162. + /*
  1163. + * Allocate the Device Mode structures.
  1164. + */
  1165. + dev_if = kmalloc( sizeof(dwc_otg_dev_if_t), GFP_KERNEL);
  1166. + if (dev_if == 0) {
  1167. + DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
  1168. + kfree( core_if );
  1169. + return 0;
  1170. + }
  1171. +
  1172. + dev_if->dev_global_regs =
  1173. + (dwc_otg_device_global_regs_t *)(reg_base + DWC_DEV_GLOBAL_REG_OFFSET);
  1174. +
  1175. + for (i=0; i<MAX_EPS_CHANNELS; i++) {
  1176. + dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
  1177. + (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
  1178. + (i * DWC_EP_REG_OFFSET));
  1179. +
  1180. + dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
  1181. + (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
  1182. + (i * DWC_EP_REG_OFFSET));
  1183. + DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
  1184. + i, &dev_if->in_ep_regs[i]->diepctl);
  1185. + DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
  1186. + i, &dev_if->out_ep_regs[i]->doepctl);
  1187. + }
  1188. + dev_if->speed = 0; // unknown
  1189. + //dev_if->num_eps = MAX_EPS_CHANNELS;
  1190. + //dev_if->num_perio_eps = 0;
  1191. +
  1192. + core_if->dev_if = dev_if;
  1193. + /*
  1194. + * Allocate the Host Mode structures.
  1195. + */
  1196. + host_if = kmalloc( sizeof(dwc_otg_host_if_t), GFP_KERNEL);
  1197. + if (host_if == 0) {
  1198. + DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_host_if_t failed\n");
  1199. + kfree( dev_if );
  1200. + kfree( core_if );
  1201. + return 0;
  1202. + }
  1203. +
  1204. + host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
  1205. + (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
  1206. + host_if->hprt0 = (uint32_t*)(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
  1207. + for (i=0; i<MAX_EPS_CHANNELS; i++) {
  1208. + host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
  1209. + (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
  1210. + (i * DWC_OTG_CHAN_REGS_OFFSET));
  1211. + DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
  1212. + i, &host_if->hc_regs[i]->hcchar);
  1213. + }
  1214. + host_if->num_host_channels = MAX_EPS_CHANNELS;
  1215. + core_if->host_if = host_if;
  1216. +
  1217. + for (i=0; i<MAX_EPS_CHANNELS; i++) {
  1218. + core_if->data_fifo[i] =
  1219. + (uint32_t *)(reg_base + DWC_OTG_DATA_FIFO_OFFSET +
  1220. + (i * DWC_OTG_DATA_FIFO_SIZE));
  1221. + DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08x\n",
  1222. + i, (unsigned)core_if->data_fifo[i]);
  1223. + } // for loop.
  1224. +
  1225. + core_if->pcgcctl = (uint32_t*)(reg_base + DWC_OTG_PCGCCTL_OFFSET);
  1226. +
  1227. + /*
  1228. + * Store the contents of the hardware configuration registers here for
  1229. + * easy access later.
  1230. + */
  1231. + core_if->hwcfg1.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg1);
  1232. + core_if->hwcfg2.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg2);
  1233. + core_if->hwcfg3.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg3);
  1234. + core_if->hwcfg4.d32 = dwc_read_reg32(&core_if->core_global_regs->ghwcfg4);
  1235. +
  1236. + DWC_DEBUGPL(DBG_CILV,"hwcfg1=%08x\n",core_if->hwcfg1.d32);
  1237. + DWC_DEBUGPL(DBG_CILV,"hwcfg2=%08x\n",core_if->hwcfg2.d32);
  1238. + DWC_DEBUGPL(DBG_CILV,"hwcfg3=%08x\n",core_if->hwcfg3.d32);
  1239. + DWC_DEBUGPL(DBG_CILV,"hwcfg4=%08x\n",core_if->hwcfg4.d32);
  1240. +
  1241. +
  1242. + DWC_DEBUGPL(DBG_CILV,"op_mode=%0x\n",core_if->hwcfg2.b.op_mode);
  1243. + DWC_DEBUGPL(DBG_CILV,"arch=%0x\n",core_if->hwcfg2.b.architecture);
  1244. + DWC_DEBUGPL(DBG_CILV,"num_dev_ep=%d\n",core_if->hwcfg2.b.num_dev_ep);
  1245. + DWC_DEBUGPL(DBG_CILV,"num_host_chan=%d\n",core_if->hwcfg2.b.num_host_chan);
  1246. + DWC_DEBUGPL(DBG_CILV,"nonperio_tx_q_depth=0x%0x\n",core_if->hwcfg2.b.nonperio_tx_q_depth);
  1247. + DWC_DEBUGPL(DBG_CILV,"host_perio_tx_q_depth=0x%0x\n",core_if->hwcfg2.b.host_perio_tx_q_depth);
  1248. + DWC_DEBUGPL(DBG_CILV,"dev_token_q_depth=0x%0x\n",core_if->hwcfg2.b.dev_token_q_depth);
  1249. +
  1250. + DWC_DEBUGPL(DBG_CILV,"Total FIFO SZ=%d\n", core_if->hwcfg3.b.dfifo_depth);
  1251. + DWC_DEBUGPL(DBG_CILV,"xfer_size_cntr_width=%0x\n", core_if->hwcfg3.b.xfer_size_cntr_width);
  1252. +
  1253. + /*
  1254. + * Set the SRP sucess bit for FS-I2c
  1255. + */
  1256. + core_if->srp_success = 0;
  1257. + core_if->srp_timer_started = 0;
  1258. +
  1259. + return core_if;
  1260. +}
  1261. +/**
  1262. + * This function frees the structures allocated by dwc_otg_cil_init().
  1263. + *
  1264. + * @param[in] _core_if The core interface pointer returned from
  1265. + * dwc_otg_cil_init().
  1266. + *
  1267. + */
  1268. +void dwc_otg_cil_remove( dwc_otg_core_if_t *_core_if )
  1269. +{
  1270. + /* Disable all interrupts */
  1271. + dwc_modify_reg32( &_core_if->core_global_regs->gahbcfg, 1, 0);
  1272. + dwc_write_reg32( &_core_if->core_global_regs->gintmsk, 0);
  1273. +
  1274. + if ( _core_if->dev_if ) {
  1275. + kfree( _core_if->dev_if );
  1276. + }
  1277. + if ( _core_if->host_if ) {
  1278. + kfree( _core_if->host_if );
  1279. + }
  1280. + kfree( _core_if );
  1281. +}
  1282. +
  1283. +/**
  1284. + * This function enables the controller's Global Interrupt in the AHB Config
  1285. + * register.
  1286. + *
  1287. + * @param[in] _core_if Programming view of DWC_otg controller.
  1288. + */
  1289. +extern void dwc_otg_enable_global_interrupts( dwc_otg_core_if_t *_core_if )
  1290. +{
  1291. + gahbcfg_data_t ahbcfg = { .d32 = 0};
  1292. + ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
  1293. + dwc_modify_reg32(&_core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
  1294. +}
  1295. +/**
  1296. + * This function disables the controller's Global Interrupt in the AHB Config
  1297. + * register.
  1298. + *
  1299. + * @param[in] _core_if Programming view of DWC_otg controller.
  1300. + */
  1301. +extern void dwc_otg_disable_global_interrupts( dwc_otg_core_if_t *_core_if )
  1302. +{
  1303. + gahbcfg_data_t ahbcfg = { .d32 = 0};
  1304. + ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
  1305. + dwc_modify_reg32(&_core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
  1306. +}
  1307. +
  1308. +/**
  1309. + * This function initializes the commmon interrupts, used in both
  1310. + * device and host modes.
  1311. + *
  1312. + * @param[in] _core_if Programming view of the DWC_otg controller
  1313. + *
  1314. + */
  1315. +static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t *_core_if)
  1316. +{
  1317. + dwc_otg_core_global_regs_t *global_regs =
  1318. + _core_if->core_global_regs;
  1319. + gintmsk_data_t intr_mask = { .d32 = 0};
  1320. + /* Clear any pending OTG Interrupts */
  1321. + dwc_write_reg32( &global_regs->gotgint, 0xFFFFFFFF);
  1322. + /* Clear any pending interrupts */
  1323. + dwc_write_reg32( &global_regs->gintsts, 0xFFFFFFFF);
  1324. + /*
  1325. + * Enable the interrupts in the GINTMSK.
  1326. + */
  1327. + intr_mask.b.modemismatch = 1;
  1328. + intr_mask.b.otgintr = 1;
  1329. + if (!_core_if->dma_enable) {
  1330. + intr_mask.b.rxstsqlvl = 1;
  1331. + }
  1332. + intr_mask.b.conidstschng = 1;
  1333. + intr_mask.b.wkupintr = 1;
  1334. + intr_mask.b.disconnect = 1;
  1335. + intr_mask.b.usbsuspend = 1;
  1336. + intr_mask.b.sessreqintr = 1;
  1337. + dwc_write_reg32( &global_regs->gintmsk, intr_mask.d32);
  1338. +}
  1339. +
  1340. +/**
  1341. + * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
  1342. + * type.
  1343. + */
  1344. +static void init_fslspclksel(dwc_otg_core_if_t *_core_if)
  1345. +{
  1346. + uint32_t val;
  1347. + hcfg_data_t hcfg;
  1348. +
  1349. + if (((_core_if->hwcfg2.b.hs_phy_type == 2) &&
  1350. + (_core_if->hwcfg2.b.fs_phy_type == 1) &&
  1351. + (_core_if->core_params->ulpi_fs_ls)) ||
  1352. + (_core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS))
  1353. + {
  1354. + /* Full speed PHY */
  1355. + val = DWC_HCFG_48_MHZ;
  1356. + } else {
  1357. + /* High speed PHY running at full speed or high speed */
  1358. + val = DWC_HCFG_30_60_MHZ;
  1359. + }
  1360. +
  1361. + DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
  1362. + hcfg.d32 = dwc_read_reg32(&_core_if->host_if->host_global_regs->hcfg);
  1363. + hcfg.b.fslspclksel = val;
  1364. + dwc_write_reg32(&_core_if->host_if->host_global_regs->hcfg, hcfg.d32);
  1365. +}
  1366. +
  1367. +/**
  1368. + * Initializes the DevSpd field of the DCFG register depending on the PHY type
  1369. + * and the enumeration speed of the device.
  1370. + */
  1371. +static void init_devspd(dwc_otg_core_if_t *_core_if)
  1372. +{
  1373. + uint32_t val;
  1374. + dcfg_data_t dcfg;
  1375. +
  1376. + if (((_core_if->hwcfg2.b.hs_phy_type == 2) &&
  1377. + (_core_if->hwcfg2.b.fs_phy_type == 1) &&
  1378. + (_core_if->core_params->ulpi_fs_ls)) ||
  1379. + (_core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS))
  1380. + {
  1381. + /* Full speed PHY */
  1382. + val = 0x3;
  1383. + } else if (_core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
  1384. + /* High speed PHY running at full speed */
  1385. + val = 0x1;
  1386. + } else {
  1387. + /* High speed PHY running at high speed */
  1388. + val = 0x0;
  1389. + }
  1390. +
  1391. + DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
  1392. + dcfg.d32 = dwc_read_reg32(&_core_if->dev_if->dev_global_regs->dcfg);
  1393. + dcfg.b.devspd = val;
  1394. + dwc_write_reg32(&_core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
  1395. +}
  1396. +
  1397. +/**
  1398. + * This function calculates the number of IN EPS
  1399. + * using GHWCFG1 and GHWCFG2 registers values
  1400. + *
  1401. + * @param _pcd the pcd structure.
  1402. + */
  1403. +static uint32_t calc_num_in_eps(dwc_otg_core_if_t * _core_if)
  1404. +{
  1405. + uint32_t num_in_eps = 0;
  1406. + uint32_t num_eps = _core_if->hwcfg2.b.num_dev_ep;
  1407. + uint32_t hwcfg1 = _core_if->hwcfg1.d32 >> 2;
  1408. + uint32_t num_tx_fifos = _core_if->hwcfg4.b.num_in_eps;
  1409. + int i;
  1410. + for (i = 0; i < num_eps; ++i) {
  1411. + if (!(hwcfg1 & 0x1))
  1412. + num_in_eps++;
  1413. + hwcfg1 >>= 2;
  1414. + }
  1415. + if (_core_if->hwcfg4.b.ded_fifo_en) {
  1416. + num_in_eps = (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
  1417. + }
  1418. + return num_in_eps;
  1419. +}
  1420. +
  1421. +
  1422. +/**
  1423. + * This function calculates the number of OUT EPS
  1424. + * using GHWCFG1 and GHWCFG2 registers values
  1425. + *
  1426. + * @param _pcd the pcd structure.
  1427. + */
  1428. +static uint32_t calc_num_out_eps(dwc_otg_core_if_t * _core_if)
  1429. +{
  1430. + uint32_t num_out_eps = 0;
  1431. + uint32_t num_eps = _core_if->hwcfg2.b.num_dev_ep;
  1432. + uint32_t hwcfg1 = _core_if->hwcfg1.d32 >> 2;
  1433. + int i;
  1434. + for (i = 0; i < num_eps; ++i) {
  1435. + if (!(hwcfg1 & 0x2))
  1436. + num_out_eps++;
  1437. + hwcfg1 >>= 2;
  1438. + }
  1439. + return num_out_eps;
  1440. +}
  1441. +/**
  1442. + * This function initializes the DWC_otg controller registers and
  1443. + * prepares the core for device mode or host mode operation.
  1444. + *
  1445. + * @param _core_if Programming view of the DWC_otg controller
  1446. + *
  1447. + */
  1448. +void dwc_otg_core_init(dwc_otg_core_if_t *_core_if)
  1449. +{
  1450. + dwc_otg_core_global_regs_t * global_regs = _core_if->core_global_regs;
  1451. + dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
  1452. + int i = 0;
  1453. + gahbcfg_data_t ahbcfg = { .d32 = 0};
  1454. + gusbcfg_data_t usbcfg = { .d32 = 0 };
  1455. + gi2cctl_data_t i2cctl = {.d32 = 0};
  1456. +
  1457. + DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n",_core_if);
  1458. +
  1459. + /* Common Initialization */
  1460. +
  1461. + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
  1462. + DWC_DEBUGPL(DBG_CIL, "USB config register: 0x%08x\n", usbcfg.d32);
  1463. +
  1464. + /* Program the ULPI External VBUS bit if needed */
  1465. + //usbcfg.b.ulpi_ext_vbus_drv = 1;
  1466. + //usbcfg.b.ulpi_ext_vbus_drv = 0;
  1467. + usbcfg.b.ulpi_ext_vbus_drv =
  1468. + (_core_if->core_params->phy_ulpi_ext_vbus == DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
  1469. +
  1470. + /* Set external TS Dline pulsing */
  1471. + usbcfg.b.term_sel_dl_pulse = (_core_if->core_params->ts_dline == 1) ? 1 : 0;
  1472. + dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
  1473. +
  1474. + /* Reset the Controller */
  1475. + dwc_otg_core_reset( _core_if );
  1476. +
  1477. + /* Initialize parameters from Hardware configuration registers. */
  1478. +#if 0
  1479. + dev_if->num_eps = _core_if->hwcfg2.b.num_dev_ep;
  1480. + dev_if->num_perio_eps = _core_if->hwcfg4.b.num_dev_perio_in_ep;
  1481. +#else
  1482. + dev_if->num_in_eps = calc_num_in_eps(_core_if);
  1483. + dev_if->num_out_eps = calc_num_out_eps(_core_if);
  1484. +#endif
  1485. + DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
  1486. + _core_if->hwcfg4.b.num_dev_perio_in_ep);
  1487. + DWC_DEBUGPL(DBG_CIL, "Is power optimization enabled? %s\n",
  1488. + _core_if->hwcfg4.b.power_optimiz ? "Yes" : "No");
  1489. + DWC_DEBUGPL(DBG_CIL, "vbus_valid filter enabled? %s\n",
  1490. + _core_if->hwcfg4.b.vbus_valid_filt_en ? "Yes" : "No");
  1491. + DWC_DEBUGPL(DBG_CIL, "iddig filter enabled? %s\n",
  1492. + _core_if->hwcfg4.b.iddig_filt_en ? "Yes" : "No");
  1493. +
  1494. + DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",_core_if->hwcfg4.b.num_dev_perio_in_ep);
  1495. + for (i=0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
  1496. + dev_if->perio_tx_fifo_size[i] =
  1497. + dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
  1498. + DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n", i,
  1499. + dev_if->perio_tx_fifo_size[i]);
  1500. + }
  1501. + for (i = 0; i < _core_if->hwcfg4.b.num_in_eps; i++) {
  1502. + dev_if->tx_fifo_size[i] =
  1503. + dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
  1504. + DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n", i,
  1505. + dev_if->perio_tx_fifo_size[i]);
  1506. + }
  1507. +
  1508. + _core_if->total_fifo_size = _core_if->hwcfg3.b.dfifo_depth;
  1509. + _core_if->rx_fifo_size = dwc_read_reg32(&global_regs->grxfsiz);
  1510. + _core_if->nperio_tx_fifo_size = dwc_read_reg32(&global_regs->gnptxfsiz) >> 16;
  1511. +
  1512. + DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", _core_if->total_fifo_size);
  1513. + DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", _core_if->rx_fifo_size);
  1514. + DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n", _core_if->nperio_tx_fifo_size);
  1515. +
  1516. + /* This programming sequence needs to happen in FS mode before any other
  1517. + * programming occurs */
  1518. + if ((_core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
  1519. + (_core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
  1520. + /* If FS mode with FS PHY */
  1521. +
  1522. + /* core_init() is now called on every switch so only call the
  1523. + * following for the first time through. */
  1524. + if (!_core_if->phy_init_done) {
  1525. + _core_if->phy_init_done = 1;
  1526. + DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
  1527. + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
  1528. + usbcfg.b.physel = 1;
  1529. + dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
  1530. +
  1531. + /* Reset after a PHY select */
  1532. + dwc_otg_core_reset( _core_if );
  1533. + }
  1534. +
  1535. + /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
  1536. + * do this on HNP Dev/Host mode switches (done in dev_init and
  1537. + * host_init). */
  1538. + if (dwc_otg_is_host_mode(_core_if)) {
  1539. + DWC_DEBUGPL(DBG_CIL, "host mode\n");
  1540. + init_fslspclksel(_core_if);
  1541. + } else {
  1542. + DWC_DEBUGPL(DBG_CIL, "device mode\n");
  1543. + init_devspd(_core_if);
  1544. + }
  1545. +
  1546. + if (_core_if->core_params->i2c_enable) {
  1547. + DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
  1548. + /* Program GUSBCFG.OtgUtmifsSel to I2C */
  1549. + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
  1550. + usbcfg.b.otgutmifssel = 1;
  1551. + dwc_write_reg32 (&global_regs->gusbcfg, usbcfg.d32);
  1552. +
  1553. + /* Program GI2CCTL.I2CEn */
  1554. + i2cctl.d32 = dwc_read_reg32(&global_regs->gi2cctl);
  1555. + i2cctl.b.i2cdevaddr = 1;
  1556. + i2cctl.b.i2cen = 0;
  1557. + dwc_write_reg32 (&global_regs->gi2cctl, i2cctl.d32);
  1558. + i2cctl.b.i2cen = 1;
  1559. + dwc_write_reg32 (&global_regs->gi2cctl, i2cctl.d32);
  1560. + }
  1561. +
  1562. + } /* endif speed == DWC_SPEED_PARAM_FULL */
  1563. + else {
  1564. + /* High speed PHY. */
  1565. + if (!_core_if->phy_init_done) {
  1566. + _core_if->phy_init_done = 1;
  1567. + DWC_DEBUGPL(DBG_CIL, "High spped PHY\n");
  1568. + /* HS PHY parameters. These parameters are preserved
  1569. + * during soft reset so only program the first time. Do
  1570. + * a soft reset immediately after setting phyif. */
  1571. + usbcfg.b.ulpi_utmi_sel = _core_if->core_params->phy_type;
  1572. + if (usbcfg.b.ulpi_utmi_sel == 2) { // winder
  1573. + DWC_DEBUGPL(DBG_CIL, "ULPI\n");
  1574. + /* ULPI interface */
  1575. + usbcfg.b.phyif = 0;
  1576. + usbcfg.b.ddrsel = _core_if->core_params->phy_ulpi_ddr;
  1577. + } else {
  1578. + /* UTMI+ interface */
  1579. + if (_core_if->core_params->phy_utmi_width == 16) {
  1580. + usbcfg.b.phyif = 1;
  1581. + DWC_DEBUGPL(DBG_CIL, "UTMI+ 16\n");
  1582. + } else {
  1583. + DWC_DEBUGPL(DBG_CIL, "UTMI+ 8\n");
  1584. + usbcfg.b.phyif = 0;
  1585. + }
  1586. + }
  1587. + dwc_write_reg32( &global_regs->gusbcfg, usbcfg.d32);
  1588. +
  1589. + /* Reset after setting the PHY parameters */
  1590. + dwc_otg_core_reset( _core_if );
  1591. + }
  1592. + }
  1593. +
  1594. + if ((_core_if->hwcfg2.b.hs_phy_type == 2) &&
  1595. + (_core_if->hwcfg2.b.fs_phy_type == 1) &&
  1596. + (_core_if->core_params->ulpi_fs_ls))
  1597. + {
  1598. + DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
  1599. + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
  1600. + usbcfg.b.ulpi_fsls = 1;
  1601. + usbcfg.b.ulpi_clk_sus_m = 1;
  1602. + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
  1603. + } else {
  1604. + DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS=0\n");
  1605. + usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
  1606. + usbcfg.b.ulpi_fsls = 0;
  1607. + usbcfg.b.ulpi_clk_sus_m = 0;
  1608. + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
  1609. + }
  1610. +
  1611. + /* Program the GAHBCFG Register.*/
  1612. + switch (_core_if->hwcfg2.b.architecture){
  1613. +
  1614. + case DWC_SLAVE_ONLY_ARCH:
  1615. + DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
  1616. + ahbcfg.b.nptxfemplvl_txfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
  1617. + ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
  1618. + _core_if->dma_enable = 0;
  1619. + break;
  1620. +
  1621. + case DWC_EXT_DMA_ARCH:
  1622. + DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
  1623. + ahbcfg.b.hburstlen = _core_if->core_params->dma_burst_size;
  1624. + _core_if->dma_enable = (_core_if->core_params->dma_enable != 0);
  1625. + break;
  1626. +
  1627. + case DWC_INT_DMA_ARCH:
  1628. + DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
  1629. + //ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR;
  1630. + ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR4;
  1631. + _core_if->dma_enable = (_core_if->core_params->dma_enable != 0);
  1632. + break;
  1633. + }
  1634. + ahbcfg.b.dmaenable = _core_if->dma_enable;
  1635. + dwc_write_reg32(&global_regs->gahbcfg, ahbcfg.d32);
  1636. + _core_if->en_multiple_tx_fifo = _core_if->hwcfg4.b.ded_fifo_en;
  1637. +
  1638. + /*
  1639. + * Program the GUSBCFG register.
  1640. + */
  1641. + usbcfg.d32 = dwc_read_reg32( &global_regs->gusbcfg );
  1642. +
  1643. + switch (_core_if->hwcfg2.b.op_mode) {
  1644. + case DWC_MODE_HNP_SRP_CAPABLE:
  1645. + usbcfg.b.hnpcap = (_core_if->core_params->otg_cap ==
  1646. + DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
  1647. + usbcfg.b.srpcap = (_core_if->core_params->otg_cap !=
  1648. + DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
  1649. + break;
  1650. +
  1651. + case DWC_MODE_SRP_ONLY_CAPABLE:
  1652. + usbcfg.b.hnpcap = 0;
  1653. + usbcfg.b.srpcap = (_core_if->core_params->otg_cap !=
  1654. + DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
  1655. + break;
  1656. +
  1657. + case DWC_MODE_NO_HNP_SRP_CAPABLE:
  1658. + usbcfg.b.hnpcap = 0;
  1659. + usbcfg.b.srpcap = 0;
  1660. + break;
  1661. +
  1662. + case DWC_MODE_SRP_CAPABLE_DEVICE:
  1663. + usbcfg.b.hnpcap = 0;
  1664. + usbcfg.b.srpcap = (_core_if->core_params->otg_cap !=
  1665. + DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
  1666. + break;
  1667. +
  1668. + case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
  1669. + usbcfg.b.hnpcap = 0;
  1670. + usbcfg.b.srpcap = 0;
  1671. + break;
  1672. +
  1673. + case DWC_MODE_SRP_CAPABLE_HOST:
  1674. + usbcfg.b.hnpcap = 0;
  1675. + usbcfg.b.srpcap = (_core_if->core_params->otg_cap !=
  1676. + DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
  1677. + break;
  1678. +
  1679. + case DWC_MODE_NO_SRP_CAPABLE_HOST:
  1680. + usbcfg.b.hnpcap = 0;
  1681. + usbcfg.b.srpcap = 0;
  1682. + break;
  1683. + }
  1684. +
  1685. + dwc_write_reg32( &global_regs->gusbcfg, usbcfg.d32);
  1686. +
  1687. + /* Enable common interrupts */
  1688. + dwc_otg_enable_common_interrupts( _core_if );
  1689. +
  1690. + /* Do device or host intialization based on mode during PCD
  1691. + * and HCD initialization */
  1692. + if (dwc_otg_is_host_mode( _core_if )) {
  1693. + DWC_DEBUGPL(DBG_ANY, "Host Mode\n" );
  1694. + _core_if->op_state = A_HOST;
  1695. + } else {
  1696. + DWC_DEBUGPL(DBG_ANY, "Device Mode\n" );
  1697. + _core_if->op_state = B_PERIPHERAL;
  1698. +#ifdef DWC_DEVICE_ONLY
  1699. + dwc_otg_core_dev_init( _core_if );
  1700. +#endif
  1701. + }
  1702. +}
  1703. +
  1704. +
  1705. +/**
  1706. + * This function enables the Device mode interrupts.
  1707. + *
  1708. + * @param _core_if Programming view of DWC_otg controller
  1709. + */
  1710. +void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t *_core_if)
  1711. +{
  1712. + gintmsk_data_t intr_mask = { .d32 = 0};
  1713. + dwc_otg_core_global_regs_t * global_regs = _core_if->core_global_regs;
  1714. +
  1715. + DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
  1716. +
  1717. + /* Disable all interrupts. */
  1718. + dwc_write_reg32( &global_regs->gintmsk, 0);
  1719. +
  1720. + /* Clear any pending interrupts */
  1721. + dwc_write_reg32( &global_regs->gintsts, 0xFFFFFFFF);
  1722. +
  1723. + /* Enable the common interrupts */
  1724. + dwc_otg_enable_common_interrupts( _core_if );
  1725. +
  1726. + /* Enable interrupts */
  1727. + intr_mask.b.usbreset = 1;
  1728. + intr_mask.b.enumdone = 1;
  1729. + //intr_mask.b.epmismatch = 1;
  1730. + intr_mask.b.inepintr = 1;
  1731. + intr_mask.b.outepintr = 1;
  1732. + intr_mask.b.erlysuspend = 1;
  1733. + if (_core_if->en_multiple_tx_fifo == 0) {
  1734. + intr_mask.b.epmismatch = 1;
  1735. + }
  1736. +
  1737. + /** @todo NGS: Should this be a module parameter? */
  1738. + intr_mask.b.isooutdrop = 1;
  1739. + intr_mask.b.eopframe = 1;
  1740. + intr_mask.b.incomplisoin = 1;
  1741. + intr_mask.b.incomplisoout = 1;
  1742. +
  1743. + dwc_modify_reg32( &global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
  1744. +
  1745. + DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
  1746. + dwc_read_reg32( &global_regs->gintmsk));
  1747. +}
  1748. +
  1749. +/**
  1750. + * This function initializes the DWC_otg controller registers for
  1751. + * device mode.
  1752. + *
  1753. + * @param _core_if Programming view of DWC_otg controller
  1754. + *
  1755. + */
  1756. +void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if)
  1757. +{
  1758. + dwc_otg_core_global_regs_t *global_regs =
  1759. + _core_if->core_global_regs;
  1760. + dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
  1761. + dwc_otg_core_params_t *params = _core_if->core_params;
  1762. + dcfg_data_t dcfg = {.d32 = 0};
  1763. + grstctl_t resetctl = { .d32=0 };
  1764. + int i;
  1765. + uint32_t rx_fifo_size;
  1766. + fifosize_data_t nptxfifosize;
  1767. + fifosize_data_t txfifosize;
  1768. + dthrctl_data_t dthrctl;
  1769. +
  1770. + fifosize_data_t ptxfifosize;
  1771. +
  1772. + /* Restart the Phy Clock */
  1773. + dwc_write_reg32(_core_if->pcgcctl, 0);
  1774. +
  1775. + /* Device configuration register */
  1776. + init_devspd(_core_if);
  1777. + dcfg.d32 = dwc_read_reg32( &dev_if->dev_global_regs->dcfg);
  1778. + dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
  1779. + dwc_write_reg32( &dev_if->dev_global_regs->dcfg, dcfg.d32 );
  1780. +
  1781. + /* Configure data FIFO sizes */
  1782. + if ( _core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo ) {
  1783. +
  1784. + DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n", _core_if->total_fifo_size);
  1785. + DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n", params->dev_rx_fifo_size);
  1786. + DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n", params->dev_nperio_tx_fifo_size);
  1787. +
  1788. + /* Rx FIFO */
  1789. + DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
  1790. + dwc_read_reg32(&global_regs->grxfsiz));
  1791. + rx_fifo_size = params->dev_rx_fifo_size;
  1792. + dwc_write_reg32( &global_regs->grxfsiz, rx_fifo_size );
  1793. + DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
  1794. + dwc_read_reg32(&global_regs->grxfsiz));
  1795. +
  1796. + /** Set Periodic Tx FIFO Mask all bits 0 */
  1797. + _core_if->p_tx_msk = 0;
  1798. +
  1799. + /** Set Tx FIFO Mask all bits 0 */
  1800. + _core_if->tx_msk = 0;
  1801. + if (_core_if->en_multiple_tx_fifo == 0) {
  1802. + /* Non-periodic Tx FIFO */
  1803. + DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
  1804. + dwc_read_reg32(&global_regs->gnptxfsiz));
  1805. + nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
  1806. + nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
  1807. + dwc_write_reg32( &global_regs->gnptxfsiz, nptxfifosize.d32 );
  1808. + DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
  1809. + dwc_read_reg32(&global_regs->gnptxfsiz));
  1810. +
  1811. +
  1812. + /**@todo NGS: Fix Periodic FIFO Sizing! */
  1813. + /*
  1814. + * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
  1815. + * Indexes of the FIFO size module parameters in the
  1816. + * dev_perio_tx_fifo_size array and the FIFO size registers in
  1817. + * the dptxfsiz array run from 0 to 14.
  1818. + */
  1819. + /** @todo Finish debug of this */
  1820. + ptxfifosize.b.startaddr =
  1821. + nptxfifosize.b.startaddr + nptxfifosize.b.depth;
  1822. + for (i = 0; i < _core_if->hwcfg4.b.num_dev_perio_in_ep;i++) {
  1823. + ptxfifosize.b.depth = params->dev_perio_tx_fifo_size[i];
  1824. + DWC_DEBUGPL(DBG_CIL,"initial dptxfsiz_dieptxf[%d]=%08x\n",
  1825. + i,dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));
  1826. + dwc_write_reg32(&global_regs->dptxfsiz_dieptxf[i],ptxfifosize.d32);
  1827. + DWC_DEBUGPL(DBG_CIL,"new dptxfsiz_dieptxf[%d]=%08x\n",
  1828. + i,dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));
  1829. + ptxfifosize.b.startaddr += ptxfifosize.b.depth;
  1830. + }
  1831. + } else {
  1832. +
  1833. + /*
  1834. + * Tx FIFOs These FIFOs are numbered from 1 to 15.
  1835. + * Indexes of the FIFO size module parameters in the
  1836. + * dev_tx_fifo_size array and the FIFO size registers in
  1837. + * the dptxfsiz_dieptxf array run from 0 to 14.
  1838. + */
  1839. +
  1840. + /* Non-periodic Tx FIFO */
  1841. + DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
  1842. + dwc_read_reg32(&global_regs->gnptxfsiz));
  1843. + nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
  1844. + nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
  1845. + dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
  1846. + DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
  1847. + dwc_read_reg32(&global_regs->gnptxfsiz));
  1848. + txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
  1849. + for (i = 1;i < _core_if->hwcfg4.b.num_dev_perio_in_ep;i++) {
  1850. + txfifosize.b.depth = params->dev_tx_fifo_size[i];
  1851. + DWC_DEBUGPL(DBG_CIL,"initial dptxfsiz_dieptxf[%d]=%08x\n",
  1852. + i,dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));
  1853. + dwc_write_reg32(&global_regs->dptxfsiz_dieptxf[i - 1],txfifosize.d32);
  1854. + DWC_DEBUGPL(DBG_CIL,"new dptxfsiz_dieptxf[%d]=%08x\n",
  1855. + i,dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i-1]));
  1856. + txfifosize.b.startaddr += txfifosize.b.depth;
  1857. + }
  1858. + }
  1859. + }
  1860. + /* Flush the FIFOs */
  1861. + dwc_otg_flush_tx_fifo(_core_if, 0x10); /* all Tx FIFOs */
  1862. + dwc_otg_flush_rx_fifo(_core_if);
  1863. +
  1864. + /* Flush the Learning Queue. */
  1865. + resetctl.b.intknqflsh = 1;
  1866. + dwc_write_reg32( &_core_if->core_global_regs->grstctl, resetctl.d32);
  1867. +
  1868. + /* Clear all pending Device Interrupts */
  1869. + dwc_write_reg32( &dev_if->dev_global_regs->diepmsk, 0 );
  1870. + dwc_write_reg32( &dev_if->dev_global_regs->doepmsk, 0 );
  1871. + dwc_write_reg32( &dev_if->dev_global_regs->daint, 0xFFFFFFFF );
  1872. + dwc_write_reg32( &dev_if->dev_global_regs->daintmsk, 0 );
  1873. +
  1874. + for (i = 0; i <= dev_if->num_in_eps; i++) {
  1875. + depctl_data_t depctl;
  1876. + depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
  1877. + if (depctl.b.epena) {
  1878. + depctl.d32 = 0;
  1879. + depctl.b.epdis = 1;
  1880. + depctl.b.snak = 1;
  1881. + } else {
  1882. + depctl.d32 = 0;
  1883. + }
  1884. + dwc_write_reg32( &dev_if->in_ep_regs[i]->diepctl, depctl.d32);
  1885. +
  1886. + dwc_write_reg32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
  1887. + dwc_write_reg32(&dev_if->in_ep_regs[i]->diepdma, 0);
  1888. + dwc_write_reg32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
  1889. + }
  1890. + for (i = 0; i <= dev_if->num_out_eps; i++) {
  1891. + depctl_data_t depctl;
  1892. + depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
  1893. + if (depctl.b.epena) {
  1894. + depctl.d32 = 0;
  1895. + depctl.b.epdis = 1;
  1896. + depctl.b.snak = 1;
  1897. + } else {
  1898. + depctl.d32 = 0;
  1899. + }
  1900. + dwc_write_reg32( &dev_if->out_ep_regs[i]->doepctl, depctl.d32);
  1901. +
  1902. + //dwc_write_reg32( &dev_if->in_ep_regs[i]->dieptsiz, 0);
  1903. + dwc_write_reg32( &dev_if->out_ep_regs[i]->doeptsiz, 0);
  1904. + //dwc_write_reg32( &dev_if->in_ep_regs[i]->diepdma, 0);
  1905. + dwc_write_reg32( &dev_if->out_ep_regs[i]->doepdma, 0);
  1906. + //dwc_write_reg32( &dev_if->in_ep_regs[i]->diepint, 0xFF);
  1907. + dwc_write_reg32( &dev_if->out_ep_regs[i]->doepint, 0xFF);
  1908. + }
  1909. +
  1910. + if (_core_if->en_multiple_tx_fifo && _core_if->dma_enable) {
  1911. + dev_if->non_iso_tx_thr_en = _core_if->core_params->thr_ctl & 0x1;
  1912. + dev_if->iso_tx_thr_en = (_core_if->core_params->thr_ctl >> 1) & 0x1;
  1913. + dev_if->rx_thr_en = (_core_if->core_params->thr_ctl >> 2) & 0x1;
  1914. + dev_if->rx_thr_length = _core_if->core_params->rx_thr_length;
  1915. + dev_if->tx_thr_length = _core_if->core_params->tx_thr_length;
  1916. + dthrctl.d32 = 0;
  1917. + dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
  1918. + dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
  1919. + dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
  1920. + dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
  1921. + dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
  1922. + dwc_write_reg32(&dev_if->dev_global_regs->dtknqr3_dthrctl,dthrctl.d32);
  1923. + DWC_DEBUGPL(DBG_CIL, "Non ISO Tx Thr - %d\nISO Tx Thr - %d\n"
  1924. + "Rx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
  1925. + dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
  1926. + dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
  1927. + dthrctl.b.rx_thr_len);
  1928. + }
  1929. + dwc_otg_enable_device_interrupts( _core_if );
  1930. + {
  1931. + diepmsk_data_t msk = {.d32 = 0};
  1932. + msk.b.txfifoundrn = 1;
  1933. + dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk, msk.d32,msk.d32);
  1934. +}
  1935. +}
  1936. +
  1937. +/**
  1938. + * This function enables the Host mode interrupts.
  1939. + *
  1940. + * @param _core_if Programming view of DWC_otg controller
  1941. + */
  1942. +void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t *_core_if)
  1943. +{
  1944. + dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
  1945. + gintmsk_data_t intr_mask = {.d32 = 0};
  1946. +
  1947. + DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
  1948. +
  1949. + /* Disable all interrupts. */
  1950. + dwc_write_reg32(&global_regs->gintmsk, 0);
  1951. +
  1952. + /* Clear any pending interrupts. */
  1953. + dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
  1954. +
  1955. + /* Enable the common interrupts */
  1956. + dwc_otg_enable_common_interrupts(_core_if);
  1957. +
  1958. + /*
  1959. + * Enable host mode interrupts without disturbing common
  1960. + * interrupts.
  1961. + */
  1962. + intr_mask.b.sofintr = 1;
  1963. + intr_mask.b.portintr = 1;
  1964. + intr_mask.b.hcintr = 1;
  1965. +
  1966. + //dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
  1967. + //dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
  1968. + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
  1969. +}
  1970. +
  1971. +/**
  1972. + * This function disables the Host Mode interrupts.
  1973. + *
  1974. + * @param _core_if Programming view of DWC_otg controller
  1975. + */
  1976. +void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t *_core_if)
  1977. +{
  1978. + dwc_otg_core_global_regs_t *global_regs =
  1979. + _core_if->core_global_regs;
  1980. + gintmsk_data_t intr_mask = {.d32 = 0};
  1981. +
  1982. + DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
  1983. +
  1984. + /*
  1985. + * Disable host mode interrupts without disturbing common
  1986. + * interrupts.
  1987. + */
  1988. + intr_mask.b.sofintr = 1;
  1989. + intr_mask.b.portintr = 1;
  1990. + intr_mask.b.hcintr = 1;
  1991. + intr_mask.b.ptxfempty = 1;
  1992. + intr_mask.b.nptxfempty = 1;
  1993. +
  1994. + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
  1995. +}
  1996. +
  1997. +#if 0
  1998. +/* currently not used, keep it here as if needed later */
  1999. +static int phy_read(dwc_otg_core_if_t * _core_if, int addr)
  2000. +{
  2001. + u32 val;
  2002. + int timeout = 10;
  2003. +
  2004. + dwc_write_reg32(&_core_if->core_global_regs->gpvndctl,
  2005. + 0x02000000 | (addr << 16));
  2006. + val = dwc_read_reg32(&_core_if->core_global_regs->gpvndctl);
  2007. + while (((val & 0x08000000) == 0) && (timeout--)) {
  2008. + udelay(1000);
  2009. + val = dwc_read_reg32(&_core_if->core_global_regs->gpvndctl);
  2010. + }
  2011. + val = dwc_read_reg32(&_core_if->core_global_regs->gpvndctl);
  2012. + printk("%s: addr=%02x regval=%02x\n", __func__, addr, val & 0x000000ff);
  2013. +
  2014. + return 0;
  2015. +}
  2016. +#endif
  2017. +
  2018. +/**
  2019. + * This function initializes the DWC_otg controller registers for
  2020. + * host mode.
  2021. + *
  2022. + * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
  2023. + * request queues. Host channels are reset to ensure that they are ready for
  2024. + * performing transfers.
  2025. + *
  2026. + * @param _core_if Programming view of DWC_otg controller
  2027. + *
  2028. + */
  2029. +void dwc_otg_core_host_init(dwc_otg_core_if_t *_core_if)
  2030. +{
  2031. + dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
  2032. + dwc_otg_host_if_t *host_if = _core_if->host_if;
  2033. + dwc_otg_core_params_t *params = _core_if->core_params;
  2034. + hprt0_data_t hprt0 = {.d32 = 0};
  2035. + fifosize_data_t nptxfifosize;
  2036. + fifosize_data_t ptxfifosize;
  2037. + int i;
  2038. + hcchar_data_t hcchar;
  2039. + hcfg_data_t hcfg;
  2040. + dwc_otg_hc_regs_t *hc_regs;
  2041. + int num_channels;
  2042. + gotgctl_data_t gotgctl = {.d32 = 0};
  2043. +
  2044. + DWC_DEBUGPL(DBG_CILV,"%s(%p)\n", __func__, _core_if);
  2045. +
  2046. + /* Restart the Phy Clock */
  2047. + dwc_write_reg32(_core_if->pcgcctl, 0);
  2048. +
  2049. + /* Initialize Host Configuration Register */
  2050. + init_fslspclksel(_core_if);
  2051. + if (_core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
  2052. + hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
  2053. + hcfg.b.fslssupp = 1;
  2054. + dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);
  2055. + }
  2056. +
  2057. + /* Configure data FIFO sizes */
  2058. + if (_core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
  2059. + DWC_DEBUGPL(DBG_CIL,"Total FIFO Size=%d\n", _core_if->total_fifo_size);
  2060. + DWC_DEBUGPL(DBG_CIL,"Rx FIFO Size=%d\n", params->host_rx_fifo_size);
  2061. + DWC_DEBUGPL(DBG_CIL,"NP Tx FIFO Size=%d\n", params->host_nperio_tx_fifo_size);
  2062. + DWC_DEBUGPL(DBG_CIL,"P Tx FIFO Size=%d\n", params->host_perio_tx_fifo_size);
  2063. +
  2064. + /* Rx FIFO */
  2065. + DWC_DEBUGPL(DBG_CIL,"initial grxfsiz=%08x\n", dwc_read_reg32(&global_regs->grxfsiz));
  2066. + dwc_write_reg32(&global_regs->grxfsiz, params->host_rx_fifo_size);
  2067. + DWC_DEBUGPL(DBG_CIL,"new grxfsiz=%08x\n", dwc_read_reg32(&global_regs->grxfsiz));
  2068. +
  2069. + /* Non-periodic Tx FIFO */
  2070. + DWC_DEBUGPL(DBG_CIL,"initial gnptxfsiz=%08x\n", dwc_read_reg32(&global_regs->gnptxfsiz));
  2071. + nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
  2072. + nptxfifosize.b.startaddr = params->host_rx_fifo_size;
  2073. + dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
  2074. + DWC_DEBUGPL(DBG_CIL,"new gnptxfsiz=%08x\n", dwc_read_reg32(&global_regs->gnptxfsiz));
  2075. +
  2076. + /* Periodic Tx FIFO */
  2077. + DWC_DEBUGPL(DBG_CIL,"initial hptxfsiz=%08x\n", dwc_read_reg32(&global_regs->hptxfsiz));
  2078. + ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
  2079. + ptxfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
  2080. + dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32);
  2081. + DWC_DEBUGPL(DBG_CIL,"new hptxfsiz=%08x\n", dwc_read_reg32(&global_regs->hptxfsiz));
  2082. + }
  2083. +
  2084. + /* Clear Host Set HNP Enable in the OTG Control Register */
  2085. + gotgctl.b.hstsethnpen = 1;
  2086. + dwc_modify_reg32( &global_regs->gotgctl, gotgctl.d32, 0);
  2087. +
  2088. + /* Make sure the FIFOs are flushed. */
  2089. + dwc_otg_flush_tx_fifo(_core_if, 0x10 /* all Tx FIFOs */);
  2090. + dwc_otg_flush_rx_fifo(_core_if);
  2091. +
  2092. + /* Flush out any leftover queued requests. */
  2093. + num_channels = _core_if->core_params->host_channels;
  2094. + for (i = 0; i < num_channels; i++) {
  2095. + hc_regs = _core_if->host_if->hc_regs[i];
  2096. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  2097. + hcchar.b.chen = 0;
  2098. + hcchar.b.chdis = 1;
  2099. + hcchar.b.epdir = 0;
  2100. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  2101. + }
  2102. +
  2103. + /* Halt all channels to put them into a known state. */
  2104. + for (i = 0; i < num_channels; i++) {
  2105. + int count = 0;
  2106. + hc_regs = _core_if->host_if->hc_regs[i];
  2107. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  2108. + hcchar.b.chen = 1;
  2109. + hcchar.b.chdis = 1;
  2110. + hcchar.b.epdir = 0;
  2111. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  2112. + DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
  2113. + do {
  2114. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  2115. + if (++count > 200) {
  2116. + DWC_ERROR("%s: Unable to clear halt on channel %d\n",
  2117. + __func__, i);
  2118. + break;
  2119. + }
  2120. + udelay(100);
  2121. + } while (hcchar.b.chen);
  2122. + }
  2123. +
  2124. + /* Turn on the vbus power. */
  2125. + DWC_PRINT("Init: Port Power? op_state=%d\n", _core_if->op_state);
  2126. + if (_core_if->op_state == A_HOST){
  2127. + hprt0.d32 = dwc_otg_read_hprt0(_core_if);
  2128. + DWC_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
  2129. + if (hprt0.b.prtpwr == 0 ) {
  2130. + hprt0.b.prtpwr = 1;
  2131. + dwc_write_reg32(host_if->hprt0, hprt0.d32);
  2132. + }
  2133. + }
  2134. +
  2135. + dwc_otg_enable_host_interrupts( _core_if );
  2136. +}
  2137. +
  2138. +/**
  2139. + * Prepares a host channel for transferring packets to/from a specific
  2140. + * endpoint. The HCCHARn register is set up with the characteristics specified
  2141. + * in _hc. Host channel interrupts that may need to be serviced while this
  2142. + * transfer is in progress are enabled.
  2143. + *
  2144. + * @param _core_if Programming view of DWC_otg controller
  2145. + * @param _hc Information needed to initialize the host channel
  2146. + */
  2147. +void dwc_otg_hc_init(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
  2148. +{
  2149. + uint32_t intr_enable;
  2150. + hcintmsk_data_t hc_intr_mask;
  2151. + gintmsk_data_t gintmsk = {.d32 = 0};
  2152. + hcchar_data_t hcchar;
  2153. + hcsplt_data_t hcsplt;
  2154. +
  2155. + uint8_t hc_num = _hc->hc_num;
  2156. + dwc_otg_host_if_t *host_if = _core_if->host_if;
  2157. + dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
  2158. +
  2159. + /* Clear old interrupt conditions for this host channel. */
  2160. + hc_intr_mask.d32 = 0xFFFFFFFF;
  2161. + hc_intr_mask.b.reserved = 0;
  2162. + dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32);
  2163. +
  2164. + /* Enable channel interrupts required for this transfer. */
  2165. + hc_intr_mask.d32 = 0;
  2166. + hc_intr_mask.b.chhltd = 1;
  2167. + if (_core_if->dma_enable) {
  2168. + hc_intr_mask.b.ahberr = 1;
  2169. + if (_hc->error_state && !_hc->do_split &&
  2170. + _hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
  2171. + hc_intr_mask.b.ack = 1;
  2172. + if (_hc->ep_is_in) {
  2173. + hc_intr_mask.b.datatglerr = 1;
  2174. + if (_hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
  2175. + hc_intr_mask.b.nak = 1;
  2176. + }
  2177. + }
  2178. + }
  2179. + } else {
  2180. + switch (_hc->ep_type) {
  2181. + case DWC_OTG_EP_TYPE_CONTROL:
  2182. + case DWC_OTG_EP_TYPE_BULK:
  2183. + hc_intr_mask.b.xfercompl = 1;
  2184. + hc_intr_mask.b.stall = 1;
  2185. + hc_intr_mask.b.xacterr = 1;
  2186. + hc_intr_mask.b.datatglerr = 1;
  2187. + if (_hc->ep_is_in) {
  2188. + hc_intr_mask.b.bblerr = 1;
  2189. + } else {
  2190. + hc_intr_mask.b.nak = 1;
  2191. + hc_intr_mask.b.nyet = 1;
  2192. + if (_hc->do_ping) {
  2193. + hc_intr_mask.b.ack = 1;
  2194. + }
  2195. + }
  2196. +
  2197. + if (_hc->do_split) {
  2198. + hc_intr_mask.b.nak = 1;
  2199. + if (_hc->complete_split) {
  2200. + hc_intr_mask.b.nyet = 1;
  2201. + }
  2202. + else {
  2203. + hc_intr_mask.b.ack = 1;
  2204. + }
  2205. + }
  2206. +
  2207. + if (_hc->error_state) {
  2208. + hc_intr_mask.b.ack = 1;
  2209. + }
  2210. + break;
  2211. + case DWC_OTG_EP_TYPE_INTR:
  2212. + hc_intr_mask.b.xfercompl = 1;
  2213. + hc_intr_mask.b.nak = 1;
  2214. + hc_intr_mask.b.stall = 1;
  2215. + hc_intr_mask.b.xacterr = 1;
  2216. + hc_intr_mask.b.datatglerr = 1;
  2217. + hc_intr_mask.b.frmovrun = 1;
  2218. +
  2219. + if (_hc->ep_is_in) {
  2220. + hc_intr_mask.b.bblerr = 1;
  2221. + }
  2222. + if (_hc->error_state) {
  2223. + hc_intr_mask.b.ack = 1;
  2224. + }
  2225. + if (_hc->do_split) {
  2226. + if (_hc->complete_split) {
  2227. + hc_intr_mask.b.nyet = 1;
  2228. + }
  2229. + else {
  2230. + hc_intr_mask.b.ack = 1;
  2231. + }
  2232. + }
  2233. + break;
  2234. + case DWC_OTG_EP_TYPE_ISOC:
  2235. + hc_intr_mask.b.xfercompl = 1;
  2236. + hc_intr_mask.b.frmovrun = 1;
  2237. + hc_intr_mask.b.ack = 1;
  2238. +
  2239. + if (_hc->ep_is_in) {
  2240. + hc_intr_mask.b.xacterr = 1;
  2241. + hc_intr_mask.b.bblerr = 1;
  2242. + }
  2243. + break;
  2244. + }
  2245. + }
  2246. + dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);
  2247. +
  2248. + /* Enable the top level host channel interrupt. */
  2249. + intr_enable = (1 << hc_num);
  2250. + dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
  2251. +
  2252. + /* Make sure host channel interrupts are enabled. */
  2253. + gintmsk.b.hcintr = 1;
  2254. + dwc_modify_reg32(&_core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
  2255. +
  2256. + /*
  2257. + * Program the HCCHARn register with the endpoint characteristics for
  2258. + * the current transfer.
  2259. + */
  2260. + hcchar.d32 = 0;
  2261. + hcchar.b.devaddr = _hc->dev_addr;
  2262. + hcchar.b.epnum = _hc->ep_num;
  2263. + hcchar.b.epdir = _hc->ep_is_in;
  2264. + hcchar.b.lspddev = (_hc->speed == DWC_OTG_EP_SPEED_LOW);
  2265. + hcchar.b.eptype = _hc->ep_type;
  2266. + hcchar.b.mps = _hc->max_packet;
  2267. +
  2268. + dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
  2269. +
  2270. + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
  2271. + DWC_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n", hcchar.b.devaddr);
  2272. + DWC_DEBUGPL(DBG_HCDV, " Ep Num: %d\n", hcchar.b.epnum);
  2273. + DWC_DEBUGPL(DBG_HCDV, " Is In: %d\n", hcchar.b.epdir);
  2274. + DWC_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
  2275. + DWC_DEBUGPL(DBG_HCDV, " Ep Type: %d\n", hcchar.b.eptype);
  2276. + DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
  2277. + DWC_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n", hcchar.b.multicnt);
  2278. +
  2279. + /*
  2280. + * Program the HCSPLIT register for SPLITs
  2281. + */
  2282. + hcsplt.d32 = 0;
  2283. + if (_hc->do_split) {
  2284. + DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", _hc->hc_num,
  2285. + _hc->complete_split ? "CSPLIT" : "SSPLIT");
  2286. + hcsplt.b.compsplt = _hc->complete_split;
  2287. + hcsplt.b.xactpos = _hc->xact_pos;
  2288. + hcsplt.b.hubaddr = _hc->hub_addr;
  2289. + hcsplt.b.prtaddr = _hc->port_addr;
  2290. + DWC_DEBUGPL(DBG_HCDV, " comp split %d\n", _hc->complete_split);
  2291. + DWC_DEBUGPL(DBG_HCDV, " xact pos %d\n", _hc->xact_pos);
  2292. + DWC_DEBUGPL(DBG_HCDV, " hub addr %d\n", _hc->hub_addr);
  2293. + DWC_DEBUGPL(DBG_HCDV, " port addr %d\n", _hc->port_addr);
  2294. + DWC_DEBUGPL(DBG_HCDV, " is_in %d\n", _hc->ep_is_in);
  2295. + DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
  2296. + DWC_DEBUGPL(DBG_HCDV, " xferlen: %d\n", _hc->xfer_len);
  2297. + }
  2298. + dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
  2299. +
  2300. +}
  2301. +
  2302. +/**
  2303. + * Attempts to halt a host channel. This function should only be called in
  2304. + * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
  2305. + * normal circumstances in DMA mode, the controller halts the channel when the
  2306. + * transfer is complete or a condition occurs that requires application
  2307. + * intervention.
  2308. + *
  2309. + * In slave mode, checks for a free request queue entry, then sets the Channel
  2310. + * Enable and Channel Disable bits of the Host Channel Characteristics
  2311. + * register of the specified channel to intiate the halt. If there is no free
  2312. + * request queue entry, sets only the Channel Disable bit of the HCCHARn
  2313. + * register to flush requests for this channel. In the latter case, sets a
  2314. + * flag to indicate that the host channel needs to be halted when a request
  2315. + * queue slot is open.
  2316. + *
  2317. + * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
  2318. + * HCCHARn register. The controller ensures there is space in the request
  2319. + * queue before submitting the halt request.
  2320. + *
  2321. + * Some time may elapse before the core flushes any posted requests for this
  2322. + * host channel and halts. The Channel Halted interrupt handler completes the
  2323. + * deactivation of the host channel.
  2324. + *
  2325. + * @param _core_if Controller register interface.
  2326. + * @param _hc Host channel to halt.
  2327. + * @param _halt_status Reason for halting the channel.
  2328. + */
  2329. +void dwc_otg_hc_halt(dwc_otg_core_if_t *_core_if,
  2330. + dwc_hc_t *_hc,
  2331. + dwc_otg_halt_status_e _halt_status)
  2332. +{
  2333. + gnptxsts_data_t nptxsts;
  2334. + hptxsts_data_t hptxsts;
  2335. + hcchar_data_t hcchar;
  2336. + dwc_otg_hc_regs_t *hc_regs;
  2337. + dwc_otg_core_global_regs_t *global_regs;
  2338. + dwc_otg_host_global_regs_t *host_global_regs;
  2339. +
  2340. + hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
  2341. + global_regs = _core_if->core_global_regs;
  2342. + host_global_regs = _core_if->host_if->host_global_regs;
  2343. +
  2344. + WARN_ON(_halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS);
  2345. +
  2346. + if (_halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
  2347. + _halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
  2348. + /*
  2349. + * Disable all channel interrupts except Ch Halted. The QTD
  2350. + * and QH state associated with this transfer has been cleared
  2351. + * (in the case of URB_DEQUEUE), so the channel needs to be
  2352. + * shut down carefully to prevent crashes.
  2353. + */
  2354. + hcintmsk_data_t hcintmsk;
  2355. + hcintmsk.d32 = 0;
  2356. + hcintmsk.b.chhltd = 1;
  2357. + dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32);
  2358. +
  2359. + /*
  2360. + * Make sure no other interrupts besides halt are currently
  2361. + * pending. Handling another interrupt could cause a crash due
  2362. + * to the QTD and QH state.
  2363. + */
  2364. + dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32);
  2365. +
  2366. + /*
  2367. + * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
  2368. + * even if the channel was already halted for some other
  2369. + * reason.
  2370. + */
  2371. + _hc->halt_status = _halt_status;
  2372. +
  2373. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  2374. + if (hcchar.b.chen == 0) {
  2375. + /*
  2376. + * The channel is either already halted or it hasn't
  2377. + * started yet. In DMA mode, the transfer may halt if
  2378. + * it finishes normally or a condition occurs that
  2379. + * requires driver intervention. Don't want to halt
  2380. + * the channel again. In either Slave or DMA mode,
  2381. + * it's possible that the transfer has been assigned
  2382. + * to a channel, but not started yet when an URB is
  2383. + * dequeued. Don't want to halt a channel that hasn't
  2384. + * started yet.
  2385. + */
  2386. + return;
  2387. + }
  2388. + }
  2389. +
  2390. + if (_hc->halt_pending) {
  2391. + /*
  2392. + * A halt has already been issued for this channel. This might
  2393. + * happen when a transfer is aborted by a higher level in
  2394. + * the stack.
  2395. + */
  2396. +#ifdef DEBUG
  2397. + DWC_PRINT("*** %s: Channel %d, _hc->halt_pending already set ***\n",
  2398. + __func__, _hc->hc_num);
  2399. +
  2400. +/* dwc_otg_dump_global_registers(_core_if); */
  2401. +/* dwc_otg_dump_host_registers(_core_if); */
  2402. +#endif
  2403. + return;
  2404. + }
  2405. +
  2406. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  2407. + hcchar.b.chen = 1;
  2408. + hcchar.b.chdis = 1;
  2409. +
  2410. + if (!_core_if->dma_enable) {
  2411. + /* Check for space in the request queue to issue the halt. */
  2412. + if (_hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
  2413. + _hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
  2414. + nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts);
  2415. + if (nptxsts.b.nptxqspcavail == 0) {
  2416. + hcchar.b.chen = 0;
  2417. + }
  2418. + } else {
  2419. + hptxsts.d32 = dwc_read_reg32(&host_global_regs->hptxsts);
  2420. + if ((hptxsts.b.ptxqspcavail == 0) || (_core_if->queuing_high_bandwidth)) {
  2421. + hcchar.b.chen = 0;
  2422. + }
  2423. + }
  2424. + }
  2425. +
  2426. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  2427. +
  2428. + _hc->halt_status = _halt_status;
  2429. +
  2430. + if (hcchar.b.chen) {
  2431. + _hc->halt_pending = 1;
  2432. + _hc->halt_on_queue = 0;
  2433. + } else {
  2434. + _hc->halt_on_queue = 1;
  2435. + }
  2436. +
  2437. + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
  2438. + DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
  2439. + DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", _hc->halt_pending);
  2440. + DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", _hc->halt_on_queue);
  2441. + DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", _hc->halt_status);
  2442. +
  2443. + return;
  2444. +}
  2445. +
  2446. +/**
  2447. + * Clears the transfer state for a host channel. This function is normally
  2448. + * called after a transfer is done and the host channel is being released.
  2449. + *
  2450. + * @param _core_if Programming view of DWC_otg controller.
  2451. + * @param _hc Identifies the host channel to clean up.
  2452. + */
  2453. +void dwc_otg_hc_cleanup(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
  2454. +{
  2455. + dwc_otg_hc_regs_t *hc_regs;
  2456. +
  2457. + _hc->xfer_started = 0;
  2458. +
  2459. + /*
  2460. + * Clear channel interrupt enables and any unhandled channel interrupt
  2461. + * conditions.
  2462. + */
  2463. + hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
  2464. + dwc_write_reg32(&hc_regs->hcintmsk, 0);
  2465. + dwc_write_reg32(&hc_regs->hcint, 0xFFFFFFFF);
  2466. +
  2467. +#ifdef DEBUG
  2468. + del_timer(&_core_if->hc_xfer_timer[_hc->hc_num]);
  2469. + {
  2470. + hcchar_data_t hcchar;
  2471. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  2472. + if (hcchar.b.chdis) {
  2473. + DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
  2474. + __func__, _hc->hc_num, hcchar.d32);
  2475. + }
  2476. + }
  2477. +#endif
  2478. +}
  2479. +
  2480. +/**
  2481. + * Sets the channel property that indicates in which frame a periodic transfer
  2482. + * should occur. This is always set to the _next_ frame. This function has no
  2483. + * effect on non-periodic transfers.
  2484. + *
  2485. + * @param _core_if Programming view of DWC_otg controller.
  2486. + * @param _hc Identifies the host channel to set up and its properties.
  2487. + * @param _hcchar Current value of the HCCHAR register for the specified host
  2488. + * channel.
  2489. + */
  2490. +static inline void hc_set_even_odd_frame(dwc_otg_core_if_t *_core_if,
  2491. + dwc_hc_t *_hc,
  2492. + hcchar_data_t *_hcchar)
  2493. +{
  2494. + if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
  2495. + _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
  2496. + hfnum_data_t hfnum;
  2497. + hfnum.d32 = dwc_read_reg32(&_core_if->host_if->host_global_regs->hfnum);
  2498. + /* 1 if _next_ frame is odd, 0 if it's even */
  2499. + _hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
  2500. +#ifdef DEBUG
  2501. + if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR && _hc->do_split && !_hc->complete_split) {
  2502. + switch (hfnum.b.frnum & 0x7) {
  2503. + case 7:
  2504. + _core_if->hfnum_7_samples++;
  2505. + _core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
  2506. + break;
  2507. + case 0:
  2508. + _core_if->hfnum_0_samples++;
  2509. + _core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
  2510. + break;
  2511. + default:
  2512. + _core_if->hfnum_other_samples++;
  2513. + _core_if->hfnum_other_frrem_accum += hfnum.b.frrem;
  2514. + break;
  2515. + }
  2516. + }
  2517. +#endif
  2518. + }
  2519. +}
  2520. +
  2521. +#ifdef DEBUG
  2522. +static void hc_xfer_timeout(unsigned long _ptr)
  2523. +{
  2524. + hc_xfer_info_t *xfer_info = (hc_xfer_info_t *)_ptr;
  2525. + int hc_num = xfer_info->hc->hc_num;
  2526. + DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
  2527. + DWC_WARN(" start_hcchar_val 0x%08x\n", xfer_info->core_if->start_hcchar_val[hc_num]);
  2528. +}
  2529. +#endif
  2530. +
  2531. +/*
  2532. + * This function does the setup for a data transfer for a host channel and
  2533. + * starts the transfer. May be called in either Slave mode or DMA mode. In
  2534. + * Slave mode, the caller must ensure that there is sufficient space in the
  2535. + * request queue and Tx Data FIFO.
  2536. + *
  2537. + * For an OUT transfer in Slave mode, it loads a data packet into the
  2538. + * appropriate FIFO. If necessary, additional data packets will be loaded in
  2539. + * the Host ISR.
  2540. + *
  2541. + * For an IN transfer in Slave mode, a data packet is requested. The data
  2542. + * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
  2543. + * additional data packets are requested in the Host ISR.
  2544. + *
  2545. + * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
  2546. + * register along with a packet count of 1 and the channel is enabled. This
  2547. + * causes a single PING transaction to occur. Other fields in HCTSIZ are
  2548. + * simply set to 0 since no data transfer occurs in this case.
  2549. + *
  2550. + * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
  2551. + * all the information required to perform the subsequent data transfer. In
  2552. + * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
  2553. + * controller performs the entire PING protocol, then starts the data
  2554. + * transfer.
  2555. + *
  2556. + * @param _core_if Programming view of DWC_otg controller.
  2557. + * @param _hc Information needed to initialize the host channel. The xfer_len
  2558. + * value may be reduced to accommodate the max widths of the XferSize and
  2559. + * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
  2560. + * to reflect the final xfer_len value.
  2561. + */
  2562. +void dwc_otg_hc_start_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
  2563. +{
  2564. + hcchar_data_t hcchar;
  2565. + hctsiz_data_t hctsiz;
  2566. + uint16_t num_packets;
  2567. + uint32_t max_hc_xfer_size = _core_if->core_params->max_transfer_size;
  2568. + uint16_t max_hc_pkt_count = _core_if->core_params->max_packet_count;
  2569. + dwc_otg_hc_regs_t *hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
  2570. +
  2571. + hctsiz.d32 = 0;
  2572. +
  2573. + if (_hc->do_ping) {
  2574. + if (!_core_if->dma_enable) {
  2575. + dwc_otg_hc_do_ping(_core_if, _hc);
  2576. + _hc->xfer_started = 1;
  2577. + return;
  2578. + } else {
  2579. + hctsiz.b.dopng = 1;
  2580. + }
  2581. + }
  2582. +
  2583. + if (_hc->do_split) {
  2584. + num_packets = 1;
  2585. +
  2586. + if (_hc->complete_split && !_hc->ep_is_in) {
  2587. + /* For CSPLIT OUT Transfer, set the size to 0 so the
  2588. + * core doesn't expect any data written to the FIFO */
  2589. + _hc->xfer_len = 0;
  2590. + } else if (_hc->ep_is_in || (_hc->xfer_len > _hc->max_packet)) {
  2591. + _hc->xfer_len = _hc->max_packet;
  2592. + } else if (!_hc->ep_is_in && (_hc->xfer_len > 188)) {
  2593. + _hc->xfer_len = 188;
  2594. + }
  2595. +
  2596. + hctsiz.b.xfersize = _hc->xfer_len;
  2597. + } else {
  2598. + /*
  2599. + * Ensure that the transfer length and packet count will fit
  2600. + * in the widths allocated for them in the HCTSIZn register.
  2601. + */
  2602. + if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
  2603. + _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
  2604. + /*
  2605. + * Make sure the transfer size is no larger than one
  2606. + * (micro)frame's worth of data. (A check was done
  2607. + * when the periodic transfer was accepted to ensure
  2608. + * that a (micro)frame's worth of data can be
  2609. + * programmed into a channel.)
  2610. + */
  2611. + uint32_t max_periodic_len = _hc->multi_count * _hc->max_packet;
  2612. + if (_hc->xfer_len > max_periodic_len) {
  2613. + _hc->xfer_len = max_periodic_len;
  2614. + } else {
  2615. + }
  2616. + } else if (_hc->xfer_len > max_hc_xfer_size) {
  2617. + /* Make sure that xfer_len is a multiple of max packet size. */
  2618. + _hc->xfer_len = max_hc_xfer_size - _hc->max_packet + 1;
  2619. + }
  2620. +
  2621. + if (_hc->xfer_len > 0) {
  2622. + num_packets = (_hc->xfer_len + _hc->max_packet - 1) / _hc->max_packet;
  2623. + if (num_packets > max_hc_pkt_count) {
  2624. + num_packets = max_hc_pkt_count;
  2625. + _hc->xfer_len = num_packets * _hc->max_packet;
  2626. + }
  2627. + } else {
  2628. + /* Need 1 packet for transfer length of 0. */
  2629. + num_packets = 1;
  2630. + }
  2631. +
  2632. + if (_hc->ep_is_in) {
  2633. + /* Always program an integral # of max packets for IN transfers. */
  2634. + _hc->xfer_len = num_packets * _hc->max_packet;
  2635. + }
  2636. +
  2637. + if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
  2638. + _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
  2639. + /*
  2640. + * Make sure that the multi_count field matches the
  2641. + * actual transfer length.
  2642. + */
  2643. + _hc->multi_count = num_packets;
  2644. +
  2645. + }
  2646. +
  2647. + if (_hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
  2648. + /* Set up the initial PID for the transfer. */
  2649. + if (_hc->speed == DWC_OTG_EP_SPEED_HIGH) {
  2650. + if (_hc->ep_is_in) {
  2651. + if (_hc->multi_count == 1) {
  2652. + _hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
  2653. + } else if (_hc->multi_count == 2) {
  2654. + _hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
  2655. + } else {
  2656. + _hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
  2657. + }
  2658. + } else {
  2659. + if (_hc->multi_count == 1) {
  2660. + _hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
  2661. + } else {
  2662. + _hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
  2663. + }
  2664. + }
  2665. + } else {
  2666. + _hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
  2667. + }
  2668. + }
  2669. +
  2670. + hctsiz.b.xfersize = _hc->xfer_len;
  2671. + }
  2672. +
  2673. + _hc->start_pkt_count = num_packets;
  2674. + hctsiz.b.pktcnt = num_packets;
  2675. + hctsiz.b.pid = _hc->data_pid_start;
  2676. + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
  2677. +
  2678. + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
  2679. + DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
  2680. + DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt);
  2681. + DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
  2682. +
  2683. + if (_core_if->dma_enable) {
  2684. +#ifdef DEBUG
  2685. +if(((uint32_t)_hc->xfer_buff)%4)
  2686. +printk("dwc_otg_hc_start_transfer _hc->xfer_buff not 4 byte alignment\n");
  2687. +#endif
  2688. + dwc_write_reg32(&hc_regs->hcdma, (uint32_t)_hc->xfer_buff);
  2689. + }
  2690. +
  2691. + /* Start the split */
  2692. + if (_hc->do_split) {
  2693. + hcsplt_data_t hcsplt;
  2694. + hcsplt.d32 = dwc_read_reg32 (&hc_regs->hcsplt);
  2695. + hcsplt.b.spltena = 1;
  2696. + dwc_write_reg32(&hc_regs->hcsplt, hcsplt.d32);
  2697. + }
  2698. +
  2699. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  2700. + hcchar.b.multicnt = _hc->multi_count;
  2701. + hc_set_even_odd_frame(_core_if, _hc, &hcchar);
  2702. +#ifdef DEBUG
  2703. + _core_if->start_hcchar_val[_hc->hc_num] = hcchar.d32;
  2704. + if (hcchar.b.chdis) {
  2705. + DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
  2706. + __func__, _hc->hc_num, hcchar.d32);
  2707. + }
  2708. +#endif
  2709. +
  2710. + /* Set host channel enable after all other setup is complete. */
  2711. + hcchar.b.chen = 1;
  2712. + hcchar.b.chdis = 0;
  2713. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  2714. +
  2715. + _hc->xfer_started = 1;
  2716. + _hc->requests++;
  2717. +
  2718. + if (!_core_if->dma_enable && !_hc->ep_is_in && _hc->xfer_len > 0) {
  2719. + /* Load OUT packet into the appropriate Tx FIFO. */
  2720. + dwc_otg_hc_write_packet(_core_if, _hc);
  2721. + }
  2722. +
  2723. +#ifdef DEBUG
  2724. + /* Start a timer for this transfer. */
  2725. + _core_if->hc_xfer_timer[_hc->hc_num].function = hc_xfer_timeout;
  2726. + _core_if->hc_xfer_info[_hc->hc_num].core_if = _core_if;
  2727. + _core_if->hc_xfer_info[_hc->hc_num].hc = _hc;
  2728. + _core_if->hc_xfer_timer[_hc->hc_num].data = (unsigned long)(&_core_if->hc_xfer_info[_hc->hc_num]);
  2729. + _core_if->hc_xfer_timer[_hc->hc_num].expires = jiffies + (HZ*10);
  2730. + add_timer(&_core_if->hc_xfer_timer[_hc->hc_num]);
  2731. +#endif
  2732. +}
  2733. +
  2734. +/**
  2735. + * This function continues a data transfer that was started by previous call
  2736. + * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
  2737. + * sufficient space in the request queue and Tx Data FIFO. This function
  2738. + * should only be called in Slave mode. In DMA mode, the controller acts
  2739. + * autonomously to complete transfers programmed to a host channel.
  2740. + *
  2741. + * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
  2742. + * if there is any data remaining to be queued. For an IN transfer, another
  2743. + * data packet is always requested. For the SETUP phase of a control transfer,
  2744. + * this function does nothing.
  2745. + *
  2746. + * @return 1 if a new request is queued, 0 if no more requests are required
  2747. + * for this transfer.
  2748. + */
  2749. +int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
  2750. +{
  2751. + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
  2752. +
  2753. + if (_hc->do_split) {
  2754. + /* SPLITs always queue just once per channel */
  2755. + return 0;
  2756. + } else if (_hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
  2757. + /* SETUPs are queued only once since they can't be NAKed. */
  2758. + return 0;
  2759. + } else if (_hc->ep_is_in) {
  2760. + /*
  2761. + * Always queue another request for other IN transfers. If
  2762. + * back-to-back INs are issued and NAKs are received for both,
  2763. + * the driver may still be processing the first NAK when the
  2764. + * second NAK is received. When the interrupt handler clears
  2765. + * the NAK interrupt for the first NAK, the second NAK will
  2766. + * not be seen. So we can't depend on the NAK interrupt
  2767. + * handler to requeue a NAKed request. Instead, IN requests
  2768. + * are issued each time this function is called. When the
  2769. + * transfer completes, the extra requests for the channel will
  2770. + * be flushed.
  2771. + */
  2772. + hcchar_data_t hcchar;
  2773. + dwc_otg_hc_regs_t *hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
  2774. +
  2775. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  2776. + hc_set_even_odd_frame(_core_if, _hc, &hcchar);
  2777. + hcchar.b.chen = 1;
  2778. + hcchar.b.chdis = 0;
  2779. + DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n", hcchar.d32);
  2780. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  2781. + _hc->requests++;
  2782. + return 1;
  2783. + } else {
  2784. + /* OUT transfers. */
  2785. + if (_hc->xfer_count < _hc->xfer_len) {
  2786. + if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
  2787. + _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
  2788. + hcchar_data_t hcchar;
  2789. + dwc_otg_hc_regs_t *hc_regs;
  2790. + hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
  2791. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  2792. + hc_set_even_odd_frame(_core_if, _hc, &hcchar);
  2793. + }
  2794. +
  2795. + /* Load OUT packet into the appropriate Tx FIFO. */
  2796. + dwc_otg_hc_write_packet(_core_if, _hc);
  2797. + _hc->requests++;
  2798. + return 1;
  2799. + } else {
  2800. + return 0;
  2801. + }
  2802. + }
  2803. +}
  2804. +
  2805. +/**
  2806. + * Starts a PING transfer. This function should only be called in Slave mode.
  2807. + * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
  2808. + */
  2809. +void dwc_otg_hc_do_ping(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
  2810. +{
  2811. + hcchar_data_t hcchar;
  2812. + hctsiz_data_t hctsiz;
  2813. + dwc_otg_hc_regs_t *hc_regs = _core_if->host_if->hc_regs[_hc->hc_num];
  2814. +
  2815. + DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _hc->hc_num);
  2816. +
  2817. + hctsiz.d32 = 0;
  2818. + hctsiz.b.dopng = 1;
  2819. + hctsiz.b.pktcnt = 1;
  2820. + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
  2821. +
  2822. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  2823. + hcchar.b.chen = 1;
  2824. + hcchar.b.chdis = 0;
  2825. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  2826. +}
  2827. +
  2828. +/*
  2829. + * This function writes a packet into the Tx FIFO associated with the Host
  2830. + * Channel. For a channel associated with a non-periodic EP, the non-periodic
  2831. + * Tx FIFO is written. For a channel associated with a periodic EP, the
  2832. + * periodic Tx FIFO is written. This function should only be called in Slave
  2833. + * mode.
  2834. + *
  2835. + * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
  2836. + * then number of bytes written to the Tx FIFO.
  2837. + */
  2838. +void dwc_otg_hc_write_packet(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
  2839. +{
  2840. + uint32_t i;
  2841. + uint32_t remaining_count;
  2842. + uint32_t byte_count;
  2843. + uint32_t dword_count;
  2844. +
  2845. + uint32_t *data_buff = (uint32_t *)(_hc->xfer_buff);
  2846. + uint32_t *data_fifo = _core_if->data_fifo[_hc->hc_num];
  2847. +
  2848. + remaining_count = _hc->xfer_len - _hc->xfer_count;
  2849. + if (remaining_count > _hc->max_packet) {
  2850. + byte_count = _hc->max_packet;
  2851. + } else {
  2852. + byte_count = remaining_count;
  2853. + }
  2854. +
  2855. + dword_count = (byte_count + 3) / 4;
  2856. +
  2857. + if ((((unsigned long)data_buff) & 0x3) == 0) {
  2858. + /* xfer_buff is DWORD aligned. */
  2859. + for (i = 0; i < dword_count; i++, data_buff++) {
  2860. + dwc_write_reg32(data_fifo, *data_buff);
  2861. + }
  2862. + } else {
  2863. + /* xfer_buff is not DWORD aligned. */
  2864. + for (i = 0; i < dword_count; i++, data_buff++) {
  2865. + dwc_write_reg32(data_fifo, get_unaligned(data_buff));
  2866. + }
  2867. + }
  2868. +
  2869. + _hc->xfer_count += byte_count;
  2870. + _hc->xfer_buff += byte_count;
  2871. +}
  2872. +
  2873. +/**
  2874. + * Gets the current USB frame number. This is the frame number from the last
  2875. + * SOF packet.
  2876. + */
  2877. +uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t *_core_if)
  2878. +{
  2879. + dsts_data_t dsts;
  2880. + dsts.d32 = dwc_read_reg32(&_core_if->dev_if->dev_global_regs->dsts);
  2881. +
  2882. + /* read current frame/microfreme number from DSTS register */
  2883. + return dsts.b.soffn;
  2884. +}
  2885. +
  2886. +/**
  2887. + * This function reads a setup packet from the Rx FIFO into the destination
  2888. + * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
  2889. + * Interrupt routine when a SETUP packet has been received in Slave mode.
  2890. + *
  2891. + * @param _core_if Programming view of DWC_otg controller.
  2892. + * @param _dest Destination buffer for packet data.
  2893. + */
  2894. +void dwc_otg_read_setup_packet(dwc_otg_core_if_t *_core_if, uint32_t *_dest)
  2895. +{
  2896. + /* Get the 8 bytes of a setup transaction data */
  2897. +
  2898. + /* Pop 2 DWORDS off the receive data FIFO into memory */
  2899. + _dest[0] = dwc_read_reg32(_core_if->data_fifo[0]);
  2900. + _dest[1] = dwc_read_reg32(_core_if->data_fifo[0]);
  2901. + //_dest[0] = dwc_read_datafifo32(_core_if->data_fifo[0]);
  2902. + //_dest[1] = dwc_read_datafifo32(_core_if->data_fifo[0]);
  2903. +}
  2904. +
  2905. +
  2906. +/**
  2907. + * This function enables EP0 OUT to receive SETUP packets and configures EP0
  2908. + * IN for transmitting packets. It is normally called when the
  2909. + * "Enumeration Done" interrupt occurs.
  2910. + *
  2911. + * @param _core_if Programming view of DWC_otg controller.
  2912. + * @param _ep The EP0 data.
  2913. + */
  2914. +void dwc_otg_ep0_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
  2915. +{
  2916. + dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
  2917. + dsts_data_t dsts;
  2918. + depctl_data_t diepctl;
  2919. + depctl_data_t doepctl;
  2920. + dctl_data_t dctl ={.d32=0};
  2921. +
  2922. + /* Read the Device Status and Endpoint 0 Control registers */
  2923. + dsts.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dsts);
  2924. + diepctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl);
  2925. + doepctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl);
  2926. +
  2927. + /* Set the MPS of the IN EP based on the enumeration speed */
  2928. + switch (dsts.b.enumspd) {
  2929. + case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
  2930. + case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
  2931. + case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
  2932. + diepctl.b.mps = DWC_DEP0CTL_MPS_64;
  2933. + break;
  2934. + case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
  2935. + diepctl.b.mps = DWC_DEP0CTL_MPS_8;
  2936. + break;
  2937. + }
  2938. +
  2939. + dwc_write_reg32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
  2940. +
  2941. + /* Enable OUT EP for receive */
  2942. + doepctl.b.epena = 1;
  2943. + dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
  2944. +
  2945. +#ifdef VERBOSE
  2946. + DWC_DEBUGPL(DBG_PCDV,"doepctl0=%0x\n",
  2947. + dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
  2948. + DWC_DEBUGPL(DBG_PCDV,"diepctl0=%0x\n",
  2949. + dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
  2950. +#endif
  2951. + dctl.b.cgnpinnak = 1;
  2952. + dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
  2953. + DWC_DEBUGPL(DBG_PCDV,"dctl=%0x\n",
  2954. + dwc_read_reg32(&dev_if->dev_global_regs->dctl));
  2955. +}
  2956. +
  2957. +/**
  2958. + * This function activates an EP. The Device EP control register for
  2959. + * the EP is configured as defined in the ep structure. Note: This
  2960. + * function is not used for EP0.
  2961. + *
  2962. + * @param _core_if Programming view of DWC_otg controller.
  2963. + * @param _ep The EP to activate.
  2964. + */
  2965. +void dwc_otg_ep_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
  2966. +{
  2967. + dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
  2968. + depctl_data_t depctl;
  2969. + volatile uint32_t *addr;
  2970. + daint_data_t daintmsk = {.d32=0};
  2971. +
  2972. + DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, _ep->num,
  2973. + (_ep->is_in?"IN":"OUT"));
  2974. +
  2975. + /* Read DEPCTLn register */
  2976. + if (_ep->is_in == 1) {
  2977. + addr = &dev_if->in_ep_regs[_ep->num]->diepctl;
  2978. + daintmsk.ep.in = 1<<_ep->num;
  2979. + } else {
  2980. + addr = &dev_if->out_ep_regs[_ep->num]->doepctl;
  2981. + daintmsk.ep.out = 1<<_ep->num;
  2982. + }
  2983. +
  2984. + /* If the EP is already active don't change the EP Control
  2985. + * register. */
  2986. + depctl.d32 = dwc_read_reg32(addr);
  2987. + if (!depctl.b.usbactep) {
  2988. + depctl.b.mps = _ep->maxpacket;
  2989. + depctl.b.eptype = _ep->type;
  2990. + depctl.b.txfnum = _ep->tx_fifo_num;
  2991. +
  2992. + if (_ep->type == DWC_OTG_EP_TYPE_ISOC) {
  2993. + depctl.b.setd0pid = 1; // ???
  2994. + } else {
  2995. + depctl.b.setd0pid = 1;
  2996. + }
  2997. + depctl.b.usbactep = 1;
  2998. +
  2999. + dwc_write_reg32(addr, depctl.d32);
  3000. + DWC_DEBUGPL(DBG_PCDV,"DEPCTL=%08x\n", dwc_read_reg32(addr));
  3001. + }
  3002. +
  3003. +
  3004. + /* Enable the Interrupt for this EP */
  3005. + dwc_modify_reg32(&dev_if->dev_global_regs->daintmsk,
  3006. + 0, daintmsk.d32);
  3007. + DWC_DEBUGPL(DBG_PCDV,"DAINTMSK=%0x\n",
  3008. + dwc_read_reg32(&dev_if->dev_global_regs->daintmsk));
  3009. + _ep->stall_clear_flag = 0;
  3010. + return;
  3011. +}
  3012. +
  3013. +/**
  3014. + * This function deactivates an EP. This is done by clearing the USB Active
  3015. + * EP bit in the Device EP control register. Note: This function is not used
  3016. + * for EP0. EP0 cannot be deactivated.
  3017. + *
  3018. + * @param _core_if Programming view of DWC_otg controller.
  3019. + * @param _ep The EP to deactivate.
  3020. + */
  3021. +void dwc_otg_ep_deactivate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
  3022. +{
  3023. + depctl_data_t depctl ={.d32 = 0};
  3024. + volatile uint32_t *addr;
  3025. + daint_data_t daintmsk = {.d32=0};
  3026. +
  3027. + /* Read DEPCTLn register */
  3028. + if (_ep->is_in == 1) {
  3029. + addr = &_core_if->dev_if->in_ep_regs[_ep->num]->diepctl;
  3030. + daintmsk.ep.in = 1<<_ep->num;
  3031. + } else {
  3032. + addr = &_core_if->dev_if->out_ep_regs[_ep->num]->doepctl;
  3033. + daintmsk.ep.out = 1<<_ep->num;
  3034. + }
  3035. +
  3036. + depctl.b.usbactep = 0;
  3037. + dwc_write_reg32(addr, depctl.d32);
  3038. +
  3039. + /* Disable the Interrupt for this EP */
  3040. + dwc_modify_reg32(&_core_if->dev_if->dev_global_regs->daintmsk,
  3041. + daintmsk.d32, 0);
  3042. +
  3043. + return;
  3044. +}
  3045. +
  3046. +/**
  3047. + * This function does the setup for a data transfer for an EP and
  3048. + * starts the transfer. For an IN transfer, the packets will be
  3049. + * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
  3050. + * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
  3051. + *
  3052. + * @param _core_if Programming view of DWC_otg controller.
  3053. + * @param _ep The EP to start the transfer on.
  3054. + */
  3055. +void dwc_otg_ep_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
  3056. +{
  3057. + /** @todo Refactor this funciton to check the transfer size
  3058. + * count value does not execed the number bits in the Transfer
  3059. + * count register. */
  3060. + depctl_data_t depctl;
  3061. + deptsiz_data_t deptsiz;
  3062. + gintmsk_data_t intr_mask = { .d32 = 0};
  3063. +
  3064. +#ifdef CHECK_PACKET_COUNTER_WIDTH
  3065. + const uint32_t MAX_XFER_SIZE =
  3066. + _core_if->core_params->max_transfer_size;
  3067. + const uint32_t MAX_PKT_COUNT =
  3068. + _core_if->core_params->max_packet_count;
  3069. + uint32_t num_packets;
  3070. + uint32_t transfer_len;
  3071. + dwc_otg_dev_out_ep_regs_t *out_regs =
  3072. + _core_if->dev_if->out_ep_regs[_ep->num];
  3073. + dwc_otg_dev_in_ep_regs_t *in_regs =
  3074. + _core_if->dev_if->in_ep_regs[_ep->num];
  3075. + gnptxsts_data_t txstatus;
  3076. +
  3077. + int lvl = SET_DEBUG_LEVEL(DBG_PCD);
  3078. +
  3079. +
  3080. + DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
  3081. + "xfer_buff=%p start_xfer_buff=%p\n",
  3082. + _ep->num, (_ep->is_in?"IN":"OUT"), _ep->xfer_len,
  3083. + _ep->xfer_count, _ep->xfer_buff, _ep->start_xfer_buff);
  3084. +
  3085. + transfer_len = _ep->xfer_len - _ep->xfer_count;
  3086. + if (transfer_len > MAX_XFER_SIZE) {
  3087. + transfer_len = MAX_XFER_SIZE;
  3088. + }
  3089. + if (transfer_len == 0) {
  3090. + num_packets = 1;
  3091. + /* OUT EP to recieve Zero-length packet set transfer
  3092. + * size to maxpacket size. */
  3093. + if (!_ep->is_in) {
  3094. + transfer_len = _ep->maxpacket;
  3095. + }
  3096. + } else {
  3097. + num_packets =
  3098. + (transfer_len + _ep->maxpacket - 1) / _ep->maxpacket;
  3099. + if (num_packets > MAX_PKT_COUNT) {
  3100. + num_packets = MAX_PKT_COUNT;
  3101. + }
  3102. + }
  3103. + DWC_DEBUGPL(DBG_PCD, "transfer_len=%d #pckt=%d\n", transfer_len,
  3104. + num_packets);
  3105. +
  3106. + deptsiz.b.xfersize = transfer_len;
  3107. + deptsiz.b.pktcnt = num_packets;
  3108. +
  3109. + /* IN endpoint */
  3110. + if (_ep->is_in == 1) {
  3111. + depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
  3112. + } else {/* OUT endpoint */
  3113. + depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
  3114. + }
  3115. +
  3116. + /* EP enable, IN data in FIFO */
  3117. + depctl.b.cnak = 1;
  3118. + depctl.b.epena = 1;
  3119. + /* IN endpoint */
  3120. + if (_ep->is_in == 1) {
  3121. + txstatus.d32 =
  3122. + dwc_read_reg32(&_core_if->core_global_regs->gnptxsts);
  3123. + if (txstatus.b.nptxqspcavail == 0) {
  3124. + DWC_DEBUGPL(DBG_ANY, "TX Queue Full (0x%0x)\n",
  3125. + txstatus.d32);
  3126. + return;
  3127. + }
  3128. + dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
  3129. + dwc_write_reg32(&in_regs->diepctl, depctl.d32);
  3130. + /**
  3131. + * Enable the Non-Periodic Tx FIFO empty interrupt, the
  3132. + * data will be written into the fifo by the ISR.
  3133. + */
  3134. + if (_core_if->dma_enable) {
  3135. + dwc_write_reg32(&in_regs->diepdma, (uint32_t) _ep->xfer_buff);
  3136. + } else {
  3137. + if (_core_if->en_multiple_tx_fifo == 0) {
  3138. + intr_mask.b.nptxfempty = 1;
  3139. + dwc_modify_reg32( &_core_if->core_global_regs->gintsts,
  3140. + intr_mask.d32, 0);
  3141. + dwc_modify_reg32( &_core_if->core_global_regs->gintmsk,
  3142. + intr_mask.d32, intr_mask.d32);
  3143. + } else {
  3144. + /* Enable the Tx FIFO Empty Interrupt for this EP */
  3145. + if (_ep->xfer_len > 0 &&
  3146. + _ep->type != DWC_OTG_EP_TYPE_ISOC) {
  3147. + uint32_t fifoemptymsk = 0;
  3148. + fifoemptymsk = (0x1 << _ep->num);
  3149. + dwc_modify_reg32(&_core_if->dev_if->dev_global_regs->
  3150. + dtknqr4_fifoemptymsk,0, fifoemptymsk);
  3151. + }
  3152. + }
  3153. + }
  3154. + } else { /* OUT endpoint */
  3155. + dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
  3156. + dwc_write_reg32(&out_regs->doepctl, depctl.d32);
  3157. + if (_core_if->dma_enable) {
  3158. + dwc_write_reg32(&out_regs->doepdma,(uint32_t) _ep->xfer_buff);
  3159. + }
  3160. + }
  3161. + DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
  3162. + dwc_read_reg32(&out_regs->doepctl),
  3163. + dwc_read_reg32(&out_regs->doeptsiz));
  3164. + DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
  3165. + dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daintmsk),
  3166. + dwc_read_reg32(&_core_if->core_global_regs->gintmsk));
  3167. +
  3168. + SET_DEBUG_LEVEL(lvl);
  3169. +#endif
  3170. + DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
  3171. +
  3172. + DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
  3173. + "xfer_buff=%p start_xfer_buff=%p\n",
  3174. + _ep->num, (_ep->is_in?"IN":"OUT"), _ep->xfer_len,
  3175. + _ep->xfer_count, _ep->xfer_buff, _ep->start_xfer_buff);
  3176. +
  3177. + /* IN endpoint */
  3178. + if (_ep->is_in == 1) {
  3179. + dwc_otg_dev_in_ep_regs_t * in_regs = _core_if->dev_if->in_ep_regs[_ep->num];
  3180. + gnptxsts_data_t gtxstatus;
  3181. + gtxstatus.d32 = dwc_read_reg32(&_core_if->core_global_regs->gnptxsts);
  3182. + if (_core_if->en_multiple_tx_fifo == 0 &&
  3183. + gtxstatus.b.nptxqspcavail == 0) {
  3184. +#ifdef DEBUG
  3185. + DWC_PRINT("TX Queue Full (0x%0x)\n", gtxstatus.d32);
  3186. +#endif
  3187. + //return;
  3188. + MDELAY(100); //james
  3189. + }
  3190. +
  3191. + depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
  3192. + deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
  3193. +
  3194. + /* Zero Length Packet? */
  3195. + if (_ep->xfer_len == 0) {
  3196. + deptsiz.b.xfersize = 0;
  3197. + deptsiz.b.pktcnt = 1;
  3198. + } else {
  3199. +
  3200. + /* Program the transfer size and packet count
  3201. + * as follows: xfersize = N * maxpacket +
  3202. + * short_packet pktcnt = N + (short_packet
  3203. + * exist ? 1 : 0)
  3204. + */
  3205. + deptsiz.b.xfersize = _ep->xfer_len;
  3206. + deptsiz.b.pktcnt = (_ep->xfer_len - 1 + _ep->maxpacket) / _ep->maxpacket;
  3207. + }
  3208. +
  3209. + dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
  3210. +
  3211. + /* Write the DMA register */
  3212. + if (_core_if->dma_enable) {
  3213. +#if 1 // winder
  3214. + dma_cache_wback_inv((unsigned long) _ep->xfer_buff, _ep->xfer_len); // winder
  3215. + dwc_write_reg32 (&(in_regs->diepdma),
  3216. + CPHYSADDR((uint32_t)_ep->xfer_buff)); // winder
  3217. +#else
  3218. + dwc_write_reg32 (&(in_regs->diepdma),
  3219. + (uint32_t)_ep->dma_addr);
  3220. +#endif
  3221. + } else {
  3222. + if (_ep->type != DWC_OTG_EP_TYPE_ISOC) {
  3223. + /**
  3224. + * Enable the Non-Periodic Tx FIFO empty interrupt,
  3225. + * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
  3226. + * the data will be written into the fifo by the ISR.
  3227. + */
  3228. + if (_core_if->en_multiple_tx_fifo == 0) {
  3229. + intr_mask.b.nptxfempty = 1;
  3230. + dwc_modify_reg32( &_core_if->core_global_regs->gintsts,
  3231. + intr_mask.d32, 0);
  3232. + dwc_modify_reg32( &_core_if->core_global_regs->gintmsk,
  3233. + intr_mask.d32, intr_mask.d32);
  3234. + } else {
  3235. + /* Enable the Tx FIFO Empty Interrupt for this EP */
  3236. + if (_ep->xfer_len > 0) {
  3237. + uint32_t fifoemptymsk = 0;
  3238. + fifoemptymsk = 1 << _ep->num;
  3239. + dwc_modify_reg32(&_core_if->dev_if->dev_global_regs->
  3240. + dtknqr4_fifoemptymsk,0,fifoemptymsk);
  3241. + }
  3242. + }
  3243. + }
  3244. + }
  3245. +
  3246. + /* EP enable, IN data in FIFO */
  3247. + depctl.b.cnak = 1;
  3248. + depctl.b.epena = 1;
  3249. + dwc_write_reg32(&in_regs->diepctl, depctl.d32);
  3250. +
  3251. + if (_core_if->dma_enable) {
  3252. + depctl.d32 = dwc_read_reg32 (&_core_if->dev_if->in_ep_regs[0]->diepctl);
  3253. + depctl.b.nextep = _ep->num;
  3254. + dwc_write_reg32 (&_core_if->dev_if->in_ep_regs[0]->diepctl, depctl.d32);
  3255. +
  3256. + }
  3257. + } else {
  3258. + /* OUT endpoint */
  3259. + dwc_otg_dev_out_ep_regs_t * out_regs = _core_if->dev_if->out_ep_regs[_ep->num];
  3260. +
  3261. + depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
  3262. + deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
  3263. +
  3264. + /* Program the transfer size and packet count as follows:
  3265. + *
  3266. + * pktcnt = N
  3267. + * xfersize = N * maxpacket
  3268. + */
  3269. + if (_ep->xfer_len == 0) {
  3270. + /* Zero Length Packet */
  3271. + deptsiz.b.xfersize = _ep->maxpacket;
  3272. + deptsiz.b.pktcnt = 1;
  3273. + } else {
  3274. + deptsiz.b.pktcnt = (_ep->xfer_len + (_ep->maxpacket - 1)) / _ep->maxpacket;
  3275. + deptsiz.b.xfersize = deptsiz.b.pktcnt * _ep->maxpacket;
  3276. + }
  3277. + dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
  3278. +
  3279. + DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
  3280. + _ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
  3281. +
  3282. + if (_core_if->dma_enable) {
  3283. +#if 1 // winder
  3284. + dwc_write_reg32 (&(out_regs->doepdma),
  3285. + CPHYSADDR((uint32_t)_ep->xfer_buff)); // winder
  3286. +#else
  3287. + dwc_write_reg32 (&(out_regs->doepdma),
  3288. + (uint32_t)_ep->dma_addr);
  3289. +#endif
  3290. + }
  3291. +
  3292. + if (_ep->type == DWC_OTG_EP_TYPE_ISOC) {
  3293. + /** @todo NGS: dpid is read-only. Use setd0pid
  3294. + * or setd1pid. */
  3295. + if (_ep->even_odd_frame) {
  3296. + depctl.b.setd1pid = 1;
  3297. + } else {
  3298. + depctl.b.setd0pid = 1;
  3299. + }
  3300. + }
  3301. +
  3302. + /* EP enable */
  3303. + depctl.b.cnak = 1;
  3304. + depctl.b.epena = 1;
  3305. +
  3306. + dwc_write_reg32(&out_regs->doepctl, depctl.d32);
  3307. +
  3308. + DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
  3309. + dwc_read_reg32(&out_regs->doepctl),
  3310. + dwc_read_reg32(&out_regs->doeptsiz));
  3311. + DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
  3312. + dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daintmsk),
  3313. + dwc_read_reg32(&_core_if->core_global_regs->gintmsk));
  3314. + }
  3315. +}
  3316. +
  3317. +
  3318. +/**
  3319. + * This function does the setup for a data transfer for EP0 and starts
  3320. + * the transfer. For an IN transfer, the packets will be loaded into
  3321. + * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
  3322. + * unloaded from the Rx FIFO in the ISR.
  3323. + *
  3324. + * @param _core_if Programming view of DWC_otg controller.
  3325. + * @param _ep The EP0 data.
  3326. + */
  3327. +void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
  3328. +{
  3329. + volatile depctl_data_t depctl;
  3330. + volatile deptsiz0_data_t deptsiz;
  3331. + gintmsk_data_t intr_mask = { .d32 = 0};
  3332. +
  3333. + DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
  3334. + "xfer_buff=%p start_xfer_buff=%p total_len=%d\n",
  3335. + _ep->num, (_ep->is_in?"IN":"OUT"), _ep->xfer_len,
  3336. + _ep->xfer_count, _ep->xfer_buff, _ep->start_xfer_buff,
  3337. + _ep->total_len);
  3338. + _ep->total_len = _ep->xfer_len;
  3339. +
  3340. + /* IN endpoint */
  3341. + if (_ep->is_in == 1) {
  3342. + dwc_otg_dev_in_ep_regs_t * in_regs = _core_if->dev_if->in_ep_regs[0];
  3343. + gnptxsts_data_t gtxstatus;
  3344. + gtxstatus.d32 = dwc_read_reg32(&_core_if->core_global_regs->gnptxsts);
  3345. + if (_core_if->en_multiple_tx_fifo == 0 &&
  3346. + gtxstatus.b.nptxqspcavail == 0) {
  3347. +#ifdef DEBUG
  3348. + deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
  3349. + DWC_DEBUGPL(DBG_PCD,"DIEPCTL0=%0x\n",
  3350. + dwc_read_reg32(&in_regs->diepctl));
  3351. + DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
  3352. + deptsiz.d32, deptsiz.b.xfersize,deptsiz.b.pktcnt);
  3353. + DWC_PRINT("TX Queue or FIFO Full (0x%0x)\n", gtxstatus.d32);
  3354. +#endif /* */
  3355. + printk("TX Queue or FIFO Full!!!!\n"); // test-only
  3356. + //return;
  3357. + MDELAY(100); //james
  3358. + }
  3359. +
  3360. + depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
  3361. + deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
  3362. +
  3363. + /* Zero Length Packet? */
  3364. + if (_ep->xfer_len == 0) {
  3365. + deptsiz.b.xfersize = 0;
  3366. + deptsiz.b.pktcnt = 1;
  3367. + } else {
  3368. + /* Program the transfer size and packet count
  3369. + * as follows: xfersize = N * maxpacket +
  3370. + * short_packet pktcnt = N + (short_packet
  3371. + * exist ? 1 : 0)
  3372. + */
  3373. + if (_ep->xfer_len > _ep->maxpacket) {
  3374. + _ep->xfer_len = _ep->maxpacket;
  3375. + deptsiz.b.xfersize = _ep->maxpacket;
  3376. + }
  3377. + else {
  3378. + deptsiz.b.xfersize = _ep->xfer_len;
  3379. + }
  3380. + deptsiz.b.pktcnt = 1;
  3381. +
  3382. + }
  3383. + dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
  3384. + DWC_DEBUGPL(DBG_PCDV, "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
  3385. + _ep->xfer_len, deptsiz.b.xfersize,deptsiz.b.pktcnt, deptsiz.d32);
  3386. +
  3387. + /* Write the DMA register */
  3388. + if (_core_if->dma_enable) {
  3389. + dwc_write_reg32(&(in_regs->diepdma), (uint32_t) _ep->dma_addr);
  3390. + }
  3391. +
  3392. + /* EP enable, IN data in FIFO */
  3393. + depctl.b.cnak = 1;
  3394. + depctl.b.epena = 1;
  3395. + dwc_write_reg32(&in_regs->diepctl, depctl.d32);
  3396. +
  3397. + /**
  3398. + * Enable the Non-Periodic Tx FIFO empty interrupt, the
  3399. + * data will be written into the fifo by the ISR.
  3400. + */
  3401. + if (!_core_if->dma_enable) {
  3402. + if (_core_if->en_multiple_tx_fifo == 0) {
  3403. + intr_mask.b.nptxfempty = 1;
  3404. + dwc_modify_reg32(&_core_if->core_global_regs->gintsts, intr_mask.d32, 0);
  3405. + dwc_modify_reg32(&_core_if->core_global_regs->gintmsk, intr_mask.d32,
  3406. + intr_mask.d32);
  3407. + } else {
  3408. + /* Enable the Tx FIFO Empty Interrupt for this EP */
  3409. + if (_ep->xfer_len > 0) {
  3410. + uint32_t fifoemptymsk = 0;
  3411. + fifoemptymsk |= 1 << _ep->num;
  3412. + dwc_modify_reg32(&_core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
  3413. + 0, fifoemptymsk);
  3414. + }
  3415. +
  3416. + }
  3417. + }
  3418. + } else {
  3419. + /* OUT endpoint */
  3420. + dwc_otg_dev_out_ep_regs_t * out_regs = _core_if->dev_if->out_ep_regs[_ep->num];
  3421. +
  3422. + depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
  3423. + deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
  3424. +
  3425. + /* Program the transfer size and packet count as follows:
  3426. + * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
  3427. + * pktcnt = N */
  3428. + if (_ep->xfer_len == 0) {
  3429. + /* Zero Length Packet */
  3430. + deptsiz.b.xfersize = _ep->maxpacket;
  3431. + deptsiz.b.pktcnt = 1;
  3432. + } else {
  3433. + deptsiz.b.pktcnt = (_ep->xfer_len + (_ep->maxpacket - 1)) / _ep->maxpacket;
  3434. + deptsiz.b.xfersize = deptsiz.b.pktcnt * _ep->maxpacket;
  3435. + }
  3436. +
  3437. + dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
  3438. + DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
  3439. + _ep->xfer_len, deptsiz.b.xfersize,deptsiz.b.pktcnt);
  3440. +
  3441. + if (_core_if->dma_enable) {
  3442. + dwc_write_reg32(&(out_regs->doepdma), (uint32_t) _ep->dma_addr);
  3443. + }
  3444. +
  3445. + /* EP enable */
  3446. + depctl.b.cnak = 1;
  3447. + depctl.b.epena = 1;
  3448. + dwc_write_reg32 (&(out_regs->doepctl), depctl.d32);
  3449. + }
  3450. +}
  3451. +
  3452. +/**
  3453. + * This function continues control IN transfers started by
  3454. + * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
  3455. + * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
  3456. + * bit for the packet count.
  3457. + *
  3458. + * @param _core_if Programming view of DWC_otg controller.
  3459. + * @param _ep The EP0 data.
  3460. + */
  3461. +void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
  3462. +{
  3463. + depctl_data_t depctl;
  3464. + deptsiz0_data_t deptsiz;
  3465. + gintmsk_data_t intr_mask = { .d32 = 0};
  3466. +
  3467. + if (_ep->is_in == 1) {
  3468. + dwc_otg_dev_in_ep_regs_t *in_regs =
  3469. + _core_if->dev_if->in_ep_regs[0];
  3470. + gnptxsts_data_t tx_status = {.d32 = 0};
  3471. +
  3472. + tx_status.d32 = dwc_read_reg32( &_core_if->core_global_regs->gnptxsts );
  3473. + /** @todo Should there be check for room in the Tx
  3474. + * Status Queue. If not remove the code above this comment. */
  3475. +
  3476. + depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
  3477. + deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
  3478. +
  3479. + /* Program the transfer size and packet count
  3480. + * as follows: xfersize = N * maxpacket +
  3481. + * short_packet pktcnt = N + (short_packet
  3482. + * exist ? 1 : 0)
  3483. + */
  3484. + deptsiz.b.xfersize = (_ep->total_len - _ep->xfer_count) > _ep->maxpacket ? _ep->maxpacket :
  3485. + (_ep->total_len - _ep->xfer_count);
  3486. + deptsiz.b.pktcnt = 1;
  3487. + _ep->xfer_len += deptsiz.b.xfersize;
  3488. +
  3489. + dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
  3490. + DWC_DEBUGPL(DBG_PCDV, "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
  3491. + _ep->xfer_len,
  3492. + deptsiz.b.xfersize, deptsiz.b.pktcnt, deptsiz.d32);
  3493. +
  3494. + /* Write the DMA register */
  3495. + if (_core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
  3496. + dwc_write_reg32 (&(in_regs->diepdma),
  3497. + CPHYSADDR((uint32_t)_ep->dma_addr)); // winder
  3498. + }
  3499. +
  3500. + /* EP enable, IN data in FIFO */
  3501. + depctl.b.cnak = 1;
  3502. + depctl.b.epena = 1;
  3503. + dwc_write_reg32(&in_regs->diepctl, depctl.d32);
  3504. +
  3505. + /**
  3506. + * Enable the Non-Periodic Tx FIFO empty interrupt, the
  3507. + * data will be written into the fifo by the ISR.
  3508. + */
  3509. + if (!_core_if->dma_enable) {
  3510. + /* First clear it from GINTSTS */
  3511. + intr_mask.b.nptxfempty = 1;
  3512. + dwc_write_reg32( &_core_if->core_global_regs->gintsts,
  3513. + intr_mask.d32 );
  3514. +
  3515. + dwc_modify_reg32( &_core_if->core_global_regs->gintmsk,
  3516. + intr_mask.d32, intr_mask.d32);
  3517. + }
  3518. +
  3519. + }
  3520. +
  3521. +}
  3522. +
  3523. +#ifdef DEBUG
  3524. +void dump_msg(const u8 *buf, unsigned int length)
  3525. +{
  3526. + unsigned int start, num, i;
  3527. + char line[52], *p;
  3528. +
  3529. + if (length >= 512)
  3530. + return;
  3531. + start = 0;
  3532. + while (length > 0) {
  3533. + num = min(length, 16u);
  3534. + p = line;
  3535. + for (i = 0; i < num; ++i) {
  3536. + if (i == 8)
  3537. + *p++ = ' ';
  3538. + sprintf(p, " %02x", buf[i]);
  3539. + p += 3;
  3540. + }
  3541. + *p = 0;
  3542. + DWC_PRINT( "%6x: %s\n", start, line);
  3543. + buf += num;
  3544. + start += num;
  3545. + length -= num;
  3546. + }
  3547. +}
  3548. +#else
  3549. +static inline void dump_msg(const u8 *buf, unsigned int length)
  3550. +{
  3551. +}
  3552. +#endif
  3553. +
  3554. +/**
  3555. + * This function writes a packet into the Tx FIFO associated with the
  3556. + * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
  3557. + * periodic EPs the periodic Tx FIFO associated with the EP is written
  3558. + * with all packets for the next micro-frame.
  3559. + *
  3560. + * @param _core_if Programming view of DWC_otg controller.
  3561. + * @param _ep The EP to write packet for.
  3562. + * @param _dma Indicates if DMA is being used.
  3563. + */
  3564. +void dwc_otg_ep_write_packet(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep, int _dma)
  3565. +{
  3566. + /**
  3567. + * The buffer is padded to DWORD on a per packet basis in
  3568. + * slave/dma mode if the MPS is not DWORD aligned. The last
  3569. + * packet, if short, is also padded to a multiple of DWORD.
  3570. + *
  3571. + * ep->xfer_buff always starts DWORD aligned in memory and is a
  3572. + * multiple of DWORD in length
  3573. + *
  3574. + * ep->xfer_len can be any number of bytes
  3575. + *
  3576. + * ep->xfer_count is a multiple of ep->maxpacket until the last
  3577. + * packet
  3578. + *
  3579. + * FIFO access is DWORD */
  3580. +
  3581. + uint32_t i;
  3582. + uint32_t byte_count;
  3583. + uint32_t dword_count;
  3584. + uint32_t *fifo;
  3585. + uint32_t *data_buff = (uint32_t *)_ep->xfer_buff;
  3586. +
  3587. + //DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, _core_if, _ep);
  3588. + if (_ep->xfer_count >= _ep->xfer_len) {
  3589. + DWC_WARN("%s() No data for EP%d!!!\n", __func__, _ep->num);
  3590. + return;
  3591. + }
  3592. +
  3593. + /* Find the byte length of the packet either short packet or MPS */
  3594. + if ((_ep->xfer_len - _ep->xfer_count) < _ep->maxpacket) {
  3595. + byte_count = _ep->xfer_len - _ep->xfer_count;
  3596. + }
  3597. + else {
  3598. + byte_count = _ep->maxpacket;
  3599. + }
  3600. +
  3601. + /* Find the DWORD length, padded by extra bytes as neccessary if MPS
  3602. + * is not a multiple of DWORD */
  3603. + dword_count = (byte_count + 3) / 4;
  3604. +
  3605. +#ifdef VERBOSE
  3606. + dump_msg(_ep->xfer_buff, byte_count);
  3607. +#endif
  3608. + if (_ep->type == DWC_OTG_EP_TYPE_ISOC) {
  3609. + /**@todo NGS Where are the Periodic Tx FIFO addresses
  3610. + * intialized? What should this be? */
  3611. + fifo = _core_if->data_fifo[_ep->tx_fifo_num];
  3612. + } else {
  3613. + fifo = _core_if->data_fifo[_ep->num];
  3614. + }
  3615. +
  3616. + DWC_DEBUGPL((DBG_PCDV|DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
  3617. + fifo, data_buff, *data_buff, byte_count);
  3618. +
  3619. +
  3620. + if (!_dma) {
  3621. + for (i=0; i<dword_count; i++, data_buff++) {
  3622. + dwc_write_reg32( fifo, *data_buff );
  3623. + }
  3624. + }
  3625. +
  3626. + _ep->xfer_count += byte_count;
  3627. + _ep->xfer_buff += byte_count;
  3628. +#if 1 // winder, why do we need this??
  3629. + _ep->dma_addr += byte_count;
  3630. +#endif
  3631. +}
  3632. +
  3633. +/**
  3634. + * Set the EP STALL.
  3635. + *
  3636. + * @param _core_if Programming view of DWC_otg controller.
  3637. + * @param _ep The EP to set the stall on.
  3638. + */
  3639. +void dwc_otg_ep_set_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
  3640. +{
  3641. + depctl_data_t depctl;
  3642. + volatile uint32_t *depctl_addr;
  3643. +
  3644. + DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _ep->num,
  3645. + (_ep->is_in?"IN":"OUT"));
  3646. +
  3647. + if (_ep->is_in == 1) {
  3648. + depctl_addr = &(_core_if->dev_if->in_ep_regs[_ep->num]->diepctl);
  3649. + depctl.d32 = dwc_read_reg32(depctl_addr);
  3650. +
  3651. + /* set the disable and stall bits */
  3652. + if (depctl.b.epena) {
  3653. + depctl.b.epdis = 1;
  3654. + }
  3655. + depctl.b.stall = 1;
  3656. + dwc_write_reg32(depctl_addr, depctl.d32);
  3657. +
  3658. + } else {
  3659. + depctl_addr = &(_core_if->dev_if->out_ep_regs[_ep->num]->doepctl);
  3660. + depctl.d32 = dwc_read_reg32(depctl_addr);
  3661. +
  3662. + /* set the stall bit */
  3663. + depctl.b.stall = 1;
  3664. + dwc_write_reg32(depctl_addr, depctl.d32);
  3665. + }
  3666. + DWC_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",dwc_read_reg32(depctl_addr));
  3667. + return;
  3668. +}
  3669. +
  3670. +/**
  3671. + * Clear the EP STALL.
  3672. + *
  3673. + * @param _core_if Programming view of DWC_otg controller.
  3674. + * @param _ep The EP to clear stall from.
  3675. + */
  3676. +void dwc_otg_ep_clear_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep)
  3677. +{
  3678. + depctl_data_t depctl;
  3679. + volatile uint32_t *depctl_addr;
  3680. +
  3681. + DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, _ep->num,
  3682. + (_ep->is_in?"IN":"OUT"));
  3683. +
  3684. + if (_ep->is_in == 1) {
  3685. + depctl_addr = &(_core_if->dev_if->in_ep_regs[_ep->num]->diepctl);
  3686. + } else {
  3687. + depctl_addr = &(_core_if->dev_if->out_ep_regs[_ep->num]->doepctl);
  3688. + }
  3689. +
  3690. + depctl.d32 = dwc_read_reg32(depctl_addr);
  3691. +
  3692. + /* clear the stall bits */
  3693. + depctl.b.stall = 0;
  3694. +
  3695. + /*
  3696. + * USB Spec 9.4.5: For endpoints using data toggle, regardless
  3697. + * of whether an endpoint has the Halt feature set, a
  3698. + * ClearFeature(ENDPOINT_HALT) request always results in the
  3699. + * data toggle being reinitialized to DATA0.
  3700. + */
  3701. + if (_ep->type == DWC_OTG_EP_TYPE_INTR ||
  3702. + _ep->type == DWC_OTG_EP_TYPE_BULK) {
  3703. + depctl.b.setd0pid = 1; /* DATA0 */
  3704. + }
  3705. +
  3706. + dwc_write_reg32(depctl_addr, depctl.d32);
  3707. + DWC_DEBUGPL(DBG_PCD,"DEPCTL=%0x\n",dwc_read_reg32(depctl_addr));
  3708. + return;
  3709. +}
  3710. +
  3711. +/**
  3712. + * This function reads a packet from the Rx FIFO into the destination
  3713. + * buffer. To read SETUP data use dwc_otg_read_setup_packet.
  3714. + *
  3715. + * @param _core_if Programming view of DWC_otg controller.
  3716. + * @param _dest Destination buffer for the packet.
  3717. + * @param _bytes Number of bytes to copy to the destination.
  3718. + */
  3719. +void dwc_otg_read_packet(dwc_otg_core_if_t *_core_if,
  3720. + uint8_t *_dest,
  3721. + uint16_t _bytes)
  3722. +{
  3723. + int i;
  3724. + int word_count = (_bytes + 3) / 4;
  3725. +
  3726. + volatile uint32_t *fifo = _core_if->data_fifo[0];
  3727. + uint32_t *data_buff = (uint32_t *)_dest;
  3728. +
  3729. + /**
  3730. + * @todo Account for the case where _dest is not dword aligned. This
  3731. + * requires reading data from the FIFO into a uint32_t temp buffer,
  3732. + * then moving it into the data buffer.
  3733. + */
  3734. +
  3735. + DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
  3736. + _core_if, _dest, _bytes);
  3737. +
  3738. + for (i=0; i<word_count; i++, data_buff++) {
  3739. + *data_buff = dwc_read_reg32(fifo);
  3740. + }
  3741. +
  3742. + return;
  3743. +}
  3744. +
  3745. +
  3746. +#ifdef DEBUG
  3747. +/**
  3748. + * This functions reads the device registers and prints them
  3749. + *
  3750. + * @param _core_if Programming view of DWC_otg controller.
  3751. + */
  3752. +void dwc_otg_dump_dev_registers(dwc_otg_core_if_t *_core_if)
  3753. +{
  3754. + int i;
  3755. + volatile uint32_t *addr;
  3756. +
  3757. + DWC_PRINT("Device Global Registers\n");
  3758. + addr=&_core_if->dev_if->dev_global_regs->dcfg;
  3759. + DWC_PRINT("DCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3760. + addr=&_core_if->dev_if->dev_global_regs->dctl;
  3761. + DWC_PRINT("DCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3762. + addr=&_core_if->dev_if->dev_global_regs->dsts;
  3763. + DWC_PRINT("DSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3764. + addr=&_core_if->dev_if->dev_global_regs->diepmsk;
  3765. + DWC_PRINT("DIEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3766. + addr=&_core_if->dev_if->dev_global_regs->doepmsk;
  3767. + DWC_PRINT("DOEPMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3768. + addr=&_core_if->dev_if->dev_global_regs->daint;
  3769. + DWC_PRINT("DAINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3770. + addr=&_core_if->dev_if->dev_global_regs->dtknqr1;
  3771. + DWC_PRINT("DTKNQR1 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3772. + if (_core_if->hwcfg2.b.dev_token_q_depth > 6) {
  3773. + addr=&_core_if->dev_if->dev_global_regs->dtknqr2;
  3774. + DWC_PRINT("DTKNQR2 @0x%08X : 0x%08X\n",
  3775. + (uint32_t)addr,dwc_read_reg32(addr));
  3776. + }
  3777. +
  3778. + addr=&_core_if->dev_if->dev_global_regs->dvbusdis;
  3779. + DWC_PRINT("DVBUSID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3780. +
  3781. + addr=&_core_if->dev_if->dev_global_regs->dvbuspulse;
  3782. + DWC_PRINT("DVBUSPULSE @0x%08X : 0x%08X\n",
  3783. + (uint32_t)addr,dwc_read_reg32(addr));
  3784. +
  3785. + if (_core_if->hwcfg2.b.dev_token_q_depth > 14) {
  3786. + addr = &_core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
  3787. + DWC_PRINT("DTKNQR3 @0x%08X : 0x%08X\n",
  3788. + (uint32_t)addr, dwc_read_reg32(addr));
  3789. + }
  3790. +
  3791. + if (_core_if->hwcfg2.b.dev_token_q_depth > 22) {
  3792. + addr = &_core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
  3793. + DWC_PRINT("DTKNQR4 @0x%08X : 0x%08X\n", (uint32_t) addr,
  3794. + dwc_read_reg32(addr));
  3795. + }
  3796. + for (i = 0; i <= _core_if->dev_if->num_in_eps; i++) {
  3797. + DWC_PRINT("Device IN EP %d Registers\n", i);
  3798. + addr=&_core_if->dev_if->in_ep_regs[i]->diepctl;
  3799. + DWC_PRINT("DIEPCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3800. + addr=&_core_if->dev_if->in_ep_regs[i]->diepint;
  3801. + DWC_PRINT("DIEPINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3802. + addr=&_core_if->dev_if->in_ep_regs[i]->dieptsiz;
  3803. + DWC_PRINT("DIETSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3804. + addr=&_core_if->dev_if->in_ep_regs[i]->diepdma;
  3805. + DWC_PRINT("DIEPDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3806. +
  3807. +addr = &_core_if->dev_if->in_ep_regs[i]->dtxfsts;
  3808. + DWC_PRINT("DTXFSTS @0x%08X : 0x%08X\n", (uint32_t) addr,
  3809. + dwc_read_reg32(addr));
  3810. + }
  3811. + for (i = 0; i <= _core_if->dev_if->num_out_eps; i++) {
  3812. + DWC_PRINT("Device OUT EP %d Registers\n", i);
  3813. + addr=&_core_if->dev_if->out_ep_regs[i]->doepctl;
  3814. + DWC_PRINT("DOEPCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3815. + addr=&_core_if->dev_if->out_ep_regs[i]->doepfn;
  3816. + DWC_PRINT("DOEPFN @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3817. + addr=&_core_if->dev_if->out_ep_regs[i]->doepint;
  3818. + DWC_PRINT("DOEPINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3819. + addr=&_core_if->dev_if->out_ep_regs[i]->doeptsiz;
  3820. + DWC_PRINT("DOETSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3821. + addr=&_core_if->dev_if->out_ep_regs[i]->doepdma;
  3822. + DWC_PRINT("DOEPDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3823. + }
  3824. + return;
  3825. +}
  3826. +
  3827. +/**
  3828. + * This function reads the host registers and prints them
  3829. + *
  3830. + * @param _core_if Programming view of DWC_otg controller.
  3831. + */
  3832. +void dwc_otg_dump_host_registers(dwc_otg_core_if_t *_core_if)
  3833. +{
  3834. + int i;
  3835. + volatile uint32_t *addr;
  3836. +
  3837. + DWC_PRINT("Host Global Registers\n");
  3838. + addr=&_core_if->host_if->host_global_regs->hcfg;
  3839. + DWC_PRINT("HCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3840. + addr=&_core_if->host_if->host_global_regs->hfir;
  3841. + DWC_PRINT("HFIR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3842. + addr=&_core_if->host_if->host_global_regs->hfnum;
  3843. + DWC_PRINT("HFNUM @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3844. + addr=&_core_if->host_if->host_global_regs->hptxsts;
  3845. + DWC_PRINT("HPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3846. + addr=&_core_if->host_if->host_global_regs->haint;
  3847. + DWC_PRINT("HAINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3848. + addr=&_core_if->host_if->host_global_regs->haintmsk;
  3849. + DWC_PRINT("HAINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3850. + addr=_core_if->host_if->hprt0;
  3851. + DWC_PRINT("HPRT0 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3852. +
  3853. + for (i=0; i<_core_if->core_params->host_channels; i++) {
  3854. + DWC_PRINT("Host Channel %d Specific Registers\n", i);
  3855. + addr=&_core_if->host_if->hc_regs[i]->hcchar;
  3856. + DWC_PRINT("HCCHAR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3857. + addr=&_core_if->host_if->hc_regs[i]->hcsplt;
  3858. + DWC_PRINT("HCSPLT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3859. + addr=&_core_if->host_if->hc_regs[i]->hcint;
  3860. + DWC_PRINT("HCINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3861. + addr=&_core_if->host_if->hc_regs[i]->hcintmsk;
  3862. + DWC_PRINT("HCINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3863. + addr=&_core_if->host_if->hc_regs[i]->hctsiz;
  3864. + DWC_PRINT("HCTSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3865. + addr=&_core_if->host_if->hc_regs[i]->hcdma;
  3866. + DWC_PRINT("HCDMA @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3867. +
  3868. + }
  3869. + return;
  3870. +}
  3871. +
  3872. +/**
  3873. + * This function reads the core global registers and prints them
  3874. + *
  3875. + * @param _core_if Programming view of DWC_otg controller.
  3876. + */
  3877. +void dwc_otg_dump_global_registers(dwc_otg_core_if_t *_core_if)
  3878. +{
  3879. + int i;
  3880. + volatile uint32_t *addr;
  3881. +
  3882. + DWC_PRINT("Core Global Registers\n");
  3883. + addr=&_core_if->core_global_regs->gotgctl;
  3884. + DWC_PRINT("GOTGCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3885. + addr=&_core_if->core_global_regs->gotgint;
  3886. + DWC_PRINT("GOTGINT @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3887. + addr=&_core_if->core_global_regs->gahbcfg;
  3888. + DWC_PRINT("GAHBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3889. + addr=&_core_if->core_global_regs->gusbcfg;
  3890. + DWC_PRINT("GUSBCFG @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3891. + addr=&_core_if->core_global_regs->grstctl;
  3892. + DWC_PRINT("GRSTCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3893. + addr=&_core_if->core_global_regs->gintsts;
  3894. + DWC_PRINT("GINTSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3895. + addr=&_core_if->core_global_regs->gintmsk;
  3896. + DWC_PRINT("GINTMSK @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3897. + addr=&_core_if->core_global_regs->grxstsr;
  3898. + DWC_PRINT("GRXSTSR @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3899. + //addr=&_core_if->core_global_regs->grxstsp;
  3900. + //DWC_PRINT("GRXSTSP @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3901. + addr=&_core_if->core_global_regs->grxfsiz;
  3902. + DWC_PRINT("GRXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3903. + addr=&_core_if->core_global_regs->gnptxfsiz;
  3904. + DWC_PRINT("GNPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3905. + addr=&_core_if->core_global_regs->gnptxsts;
  3906. + DWC_PRINT("GNPTXSTS @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3907. + addr=&_core_if->core_global_regs->gi2cctl;
  3908. + DWC_PRINT("GI2CCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3909. + addr=&_core_if->core_global_regs->gpvndctl;
  3910. + DWC_PRINT("GPVNDCTL @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3911. + addr=&_core_if->core_global_regs->ggpio;
  3912. + DWC_PRINT("GGPIO @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3913. + addr=&_core_if->core_global_regs->guid;
  3914. + DWC_PRINT("GUID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3915. + addr=&_core_if->core_global_regs->gsnpsid;
  3916. + DWC_PRINT("GSNPSID @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3917. + addr=&_core_if->core_global_regs->ghwcfg1;
  3918. + DWC_PRINT("GHWCFG1 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3919. + addr=&_core_if->core_global_regs->ghwcfg2;
  3920. + DWC_PRINT("GHWCFG2 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3921. + addr=&_core_if->core_global_regs->ghwcfg3;
  3922. + DWC_PRINT("GHWCFG3 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3923. + addr=&_core_if->core_global_regs->ghwcfg4;
  3924. + DWC_PRINT("GHWCFG4 @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3925. + addr=&_core_if->core_global_regs->hptxfsiz;
  3926. + DWC_PRINT("HPTXFSIZ @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
  3927. +
  3928. + for (i=0; i<_core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
  3929. + addr=&_core_if->core_global_regs->dptxfsiz_dieptxf[i];
  3930. + DWC_PRINT("DPTXFSIZ[%d] @0x%08X : 0x%08X\n",i,(uint32_t)addr,dwc_read_reg32(addr));
  3931. + }
  3932. +
  3933. +}
  3934. +#endif
  3935. +
  3936. +/**
  3937. + * Flush a Tx FIFO.
  3938. + *
  3939. + * @param _core_if Programming view of DWC_otg controller.
  3940. + * @param _num Tx FIFO to flush.
  3941. + */
  3942. +extern void dwc_otg_flush_tx_fifo( dwc_otg_core_if_t *_core_if,
  3943. + const int _num )
  3944. +{
  3945. + dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
  3946. + volatile grstctl_t greset = { .d32 = 0};
  3947. + int count = 0;
  3948. +
  3949. + DWC_DEBUGPL((DBG_CIL|DBG_PCDV), "Flush Tx FIFO %d\n", _num);
  3950. +
  3951. + greset.b.txfflsh = 1;
  3952. + greset.b.txfnum = _num;
  3953. + dwc_write_reg32( &global_regs->grstctl, greset.d32 );
  3954. +
  3955. + do {
  3956. + greset.d32 = dwc_read_reg32( &global_regs->grstctl);
  3957. + if (++count > 10000){
  3958. + DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
  3959. + __func__, greset.d32,
  3960. + dwc_read_reg32( &global_regs->gnptxsts));
  3961. + break;
  3962. + }
  3963. +
  3964. + udelay(1);
  3965. + } while (greset.b.txfflsh == 1);
  3966. + /* Wait for 3 PHY Clocks*/
  3967. + UDELAY(1);
  3968. +}
  3969. +
  3970. +/**
  3971. + * Flush Rx FIFO.
  3972. + *
  3973. + * @param _core_if Programming view of DWC_otg controller.
  3974. + */
  3975. +extern void dwc_otg_flush_rx_fifo( dwc_otg_core_if_t *_core_if )
  3976. +{
  3977. + dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
  3978. + volatile grstctl_t greset = { .d32 = 0};
  3979. + int count = 0;
  3980. +
  3981. + DWC_DEBUGPL((DBG_CIL|DBG_PCDV), "%s\n", __func__);
  3982. + /*
  3983. + *
  3984. + */
  3985. + greset.b.rxfflsh = 1;
  3986. + dwc_write_reg32( &global_regs->grstctl, greset.d32 );
  3987. +
  3988. + do {
  3989. + greset.d32 = dwc_read_reg32( &global_regs->grstctl);
  3990. + if (++count > 10000){
  3991. + DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
  3992. + greset.d32);
  3993. + break;
  3994. + }
  3995. + } while (greset.b.rxfflsh == 1);
  3996. + /* Wait for 3 PHY Clocks*/
  3997. + UDELAY(1);
  3998. +}
  3999. +
  4000. +/**
  4001. + * Do core a soft reset of the core. Be careful with this because it
  4002. + * resets all the internal state machines of the core.
  4003. + */
  4004. +
  4005. +void dwc_otg_core_reset(dwc_otg_core_if_t *_core_if)
  4006. +{
  4007. + dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;
  4008. + volatile grstctl_t greset = { .d32 = 0};
  4009. + int count = 0;
  4010. +
  4011. + DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
  4012. + /* Wait for AHB master IDLE state. */
  4013. + do {
  4014. + UDELAY(10);
  4015. + greset.d32 = dwc_read_reg32( &global_regs->grstctl);
  4016. + if (++count > 100000){
  4017. + DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x %x\n", __func__,
  4018. + greset.d32, greset.b.ahbidle);
  4019. + return;
  4020. + }
  4021. + } while (greset.b.ahbidle == 0);
  4022. +
  4023. +// winder add.
  4024. +#if 1
  4025. + /* Note: Actually, I don't exactly why we need to put delay here. */
  4026. + MDELAY(100);
  4027. +#endif
  4028. + /* Core Soft Reset */
  4029. + count = 0;
  4030. + greset.b.csftrst = 1;
  4031. + dwc_write_reg32( &global_regs->grstctl, greset.d32 );
  4032. +// winder add.
  4033. +#if 1
  4034. + /* Note: Actually, I don't exactly why we need to put delay here. */
  4035. + MDELAY(100);
  4036. +#endif
  4037. + do {
  4038. + greset.d32 = dwc_read_reg32( &global_regs->grstctl);
  4039. + if (++count > 10000){
  4040. + DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n", __func__,
  4041. + greset.d32);
  4042. + break;
  4043. + }
  4044. + udelay(1);
  4045. + } while (greset.b.csftrst == 1);
  4046. + /* Wait for 3 PHY Clocks*/
  4047. + //DWC_PRINT("100ms\n");
  4048. + MDELAY(100);
  4049. +}
  4050. +
  4051. +
  4052. +
  4053. +/**
  4054. + * Register HCD callbacks. The callbacks are used to start and stop
  4055. + * the HCD for interrupt processing.
  4056. + *
  4057. + * @param _core_if Programming view of DWC_otg controller.
  4058. + * @param _cb the HCD callback structure.
  4059. + * @param _p pointer to be passed to callback function (usb_hcd*).
  4060. + */
  4061. +extern void dwc_otg_cil_register_hcd_callbacks( dwc_otg_core_if_t *_core_if,
  4062. + dwc_otg_cil_callbacks_t *_cb,
  4063. + void *_p)
  4064. +{
  4065. + _core_if->hcd_cb = _cb;
  4066. + _cb->p = _p;
  4067. +}
  4068. +
  4069. +/**
  4070. + * Register PCD callbacks. The callbacks are used to start and stop
  4071. + * the PCD for interrupt processing.
  4072. + *
  4073. + * @param _core_if Programming view of DWC_otg controller.
  4074. + * @param _cb the PCD callback structure.
  4075. + * @param _p pointer to be passed to callback function (pcd*).
  4076. + */
  4077. +extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if,
  4078. + dwc_otg_cil_callbacks_t *_cb,
  4079. + void *_p)
  4080. +{
  4081. + _core_if->pcd_cb = _cb;
  4082. + _cb->p = _p;
  4083. +}
  4084. +
  4085. diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.h b/drivers/usb/dwc_otg/dwc_otg_cil.h
  4086. new file mode 100644
  4087. index 0000000..bbb9516
  4088. --- /dev/null
  4089. +++ b/drivers/usb/dwc_otg/dwc_otg_cil.h
  4090. @@ -0,0 +1,911 @@
  4091. +/* ==========================================================================
  4092. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_cil.h $
  4093. + * $Revision: 1.1.1.1 $
  4094. + * $Date: 2009-04-17 06:15:34 $
  4095. + * $Change: 631780 $
  4096. + *
  4097. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  4098. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  4099. + * otherwise expressly agreed to in writing between Synopsys and you.
  4100. + *
  4101. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  4102. + * any End User Software License Agreement or Agreement for Licensed Product
  4103. + * with Synopsys or any supplement thereto. You are permitted to use and
  4104. + * redistribute this Software in source and binary forms, with or without
  4105. + * modification, provided that redistributions of source code must retain this
  4106. + * notice. You may not view, use, disclose, copy or distribute this file or
  4107. + * any information contained herein except pursuant to this license grant from
  4108. + * Synopsys. If you do not agree with this notice, including the disclaimer
  4109. + * below, then you are not authorized to use the Software.
  4110. + *
  4111. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  4112. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  4113. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  4114. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  4115. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  4116. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  4117. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  4118. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  4119. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  4120. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  4121. + * DAMAGE.
  4122. + * ========================================================================== */
  4123. +
  4124. +#if !defined(__DWC_CIL_H__)
  4125. +#define __DWC_CIL_H__
  4126. +
  4127. +#include "dwc_otg_plat.h"
  4128. +
  4129. +#include "dwc_otg_regs.h"
  4130. +#ifdef DEBUG
  4131. +#include "linux/timer.h"
  4132. +#endif
  4133. +
  4134. +/* the OTG capabilities. */
  4135. +#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0
  4136. +#define DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE 1
  4137. +#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
  4138. +/* the maximum speed of operation in host and device mode. */
  4139. +#define DWC_SPEED_PARAM_HIGH 0
  4140. +#define DWC_SPEED_PARAM_FULL 1
  4141. +/* the PHY clock rate in low power mode when connected to a
  4142. + * Low Speed device in host mode. */
  4143. +#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
  4144. +#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
  4145. +/* the type of PHY interface to use. */
  4146. +#define DWC_PHY_TYPE_PARAM_FS 0
  4147. +#define DWC_PHY_TYPE_PARAM_UTMI 1
  4148. +#define DWC_PHY_TYPE_PARAM_ULPI 2
  4149. +/* whether to use the internal or external supply to
  4150. + * drive the vbus with a ULPI phy. */
  4151. +#define DWC_PHY_ULPI_INTERNAL_VBUS 0
  4152. +#define DWC_PHY_ULPI_EXTERNAL_VBUS 1
  4153. +/* EP type. */
  4154. +
  4155. +/**
  4156. + * @file
  4157. + * This file contains the interface to the Core Interface Layer.
  4158. + */
  4159. +
  4160. +/**
  4161. + * The <code>dwc_ep</code> structure represents the state of a single
  4162. + * endpoint when acting in device mode. It contains the data items
  4163. + * needed for an endpoint to be activated and transfer packets.
  4164. + */
  4165. +typedef struct dwc_ep {
  4166. + /** EP number used for register address lookup */
  4167. + uint8_t num;
  4168. + /** EP direction 0 = OUT */
  4169. + unsigned is_in : 1;
  4170. + /** EP active. */
  4171. + unsigned active : 1;
  4172. +
  4173. + /** Periodic Tx FIFO # for IN EPs For INTR EP set to 0 to use non-periodic Tx FIFO
  4174. + If dedicated Tx FIFOs are enabled for all IN Eps - Tx FIFO # FOR IN EPs*/
  4175. + unsigned tx_fifo_num : 4;
  4176. + /** EP type: 0 - Control, 1 - ISOC, 2 - BULK, 3 - INTR */
  4177. + unsigned type : 2;
  4178. +#define DWC_OTG_EP_TYPE_CONTROL 0
  4179. +#define DWC_OTG_EP_TYPE_ISOC 1
  4180. +#define DWC_OTG_EP_TYPE_BULK 2
  4181. +#define DWC_OTG_EP_TYPE_INTR 3
  4182. +
  4183. + /** DATA start PID for INTR and BULK EP */
  4184. + unsigned data_pid_start : 1;
  4185. + /** Frame (even/odd) for ISOC EP */
  4186. + unsigned even_odd_frame : 1;
  4187. + /** Max Packet bytes */
  4188. + unsigned maxpacket : 11;
  4189. +
  4190. + /** @name Transfer state */
  4191. + /** @{ */
  4192. +
  4193. + /**
  4194. + * Pointer to the beginning of the transfer buffer -- do not modify
  4195. + * during transfer.
  4196. + */
  4197. +
  4198. + uint32_t dma_addr;
  4199. +
  4200. + uint8_t *start_xfer_buff;
  4201. + /** pointer to the transfer buffer */
  4202. + uint8_t *xfer_buff;
  4203. + /** Number of bytes to transfer */
  4204. + unsigned xfer_len : 19;
  4205. + /** Number of bytes transferred. */
  4206. + unsigned xfer_count : 19;
  4207. + /** Sent ZLP */
  4208. + unsigned sent_zlp : 1;
  4209. + /** Total len for control transfer */
  4210. + unsigned total_len : 19;
  4211. +
  4212. + /** stall clear flag */
  4213. + unsigned stall_clear_flag : 1;
  4214. +
  4215. + /** @} */
  4216. +} dwc_ep_t;
  4217. +
  4218. +/*
  4219. + * Reasons for halting a host channel.
  4220. + */
  4221. +typedef enum dwc_otg_halt_status {
  4222. + DWC_OTG_HC_XFER_NO_HALT_STATUS,
  4223. + DWC_OTG_HC_XFER_COMPLETE,
  4224. + DWC_OTG_HC_XFER_URB_COMPLETE,
  4225. + DWC_OTG_HC_XFER_ACK,
  4226. + DWC_OTG_HC_XFER_NAK,
  4227. + DWC_OTG_HC_XFER_NYET,
  4228. + DWC_OTG_HC_XFER_STALL,
  4229. + DWC_OTG_HC_XFER_XACT_ERR,
  4230. + DWC_OTG_HC_XFER_FRAME_OVERRUN,
  4231. + DWC_OTG_HC_XFER_BABBLE_ERR,
  4232. + DWC_OTG_HC_XFER_DATA_TOGGLE_ERR,
  4233. + DWC_OTG_HC_XFER_AHB_ERR,
  4234. + DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE,
  4235. + DWC_OTG_HC_XFER_URB_DEQUEUE
  4236. +} dwc_otg_halt_status_e;
  4237. +
  4238. +/**
  4239. + * Host channel descriptor. This structure represents the state of a single
  4240. + * host channel when acting in host mode. It contains the data items needed to
  4241. + * transfer packets to an endpoint via a host channel.
  4242. + */
  4243. +typedef struct dwc_hc {
  4244. + /** Host channel number used for register address lookup */
  4245. + uint8_t hc_num;
  4246. +
  4247. + /** Device to access */
  4248. + unsigned dev_addr : 7;
  4249. +
  4250. + /** EP to access */
  4251. + unsigned ep_num : 4;
  4252. +
  4253. + /** EP direction. 0: OUT, 1: IN */
  4254. + unsigned ep_is_in : 1;
  4255. +
  4256. + /**
  4257. + * EP speed.
  4258. + * One of the following values:
  4259. + * - DWC_OTG_EP_SPEED_LOW
  4260. + * - DWC_OTG_EP_SPEED_FULL
  4261. + * - DWC_OTG_EP_SPEED_HIGH
  4262. + */
  4263. + unsigned speed : 2;
  4264. +#define DWC_OTG_EP_SPEED_LOW 0
  4265. +#define DWC_OTG_EP_SPEED_FULL 1
  4266. +#define DWC_OTG_EP_SPEED_HIGH 2
  4267. +
  4268. + /**
  4269. + * Endpoint type.
  4270. + * One of the following values:
  4271. + * - DWC_OTG_EP_TYPE_CONTROL: 0
  4272. + * - DWC_OTG_EP_TYPE_ISOC: 1
  4273. + * - DWC_OTG_EP_TYPE_BULK: 2
  4274. + * - DWC_OTG_EP_TYPE_INTR: 3
  4275. + */
  4276. + unsigned ep_type : 2;
  4277. +
  4278. + /** Max packet size in bytes */
  4279. + unsigned max_packet : 11;
  4280. +
  4281. + /**
  4282. + * PID for initial transaction.
  4283. + * 0: DATA0,<br>
  4284. + * 1: DATA2,<br>
  4285. + * 2: DATA1,<br>
  4286. + * 3: MDATA (non-Control EP),
  4287. + * SETUP (Control EP)
  4288. + */
  4289. + unsigned data_pid_start : 2;
  4290. +#define DWC_OTG_HC_PID_DATA0 0
  4291. +#define DWC_OTG_HC_PID_DATA2 1
  4292. +#define DWC_OTG_HC_PID_DATA1 2
  4293. +#define DWC_OTG_HC_PID_MDATA 3
  4294. +#define DWC_OTG_HC_PID_SETUP 3
  4295. +
  4296. + /** Number of periodic transactions per (micro)frame */
  4297. + unsigned multi_count: 2;
  4298. +
  4299. + /** @name Transfer State */
  4300. + /** @{ */
  4301. +
  4302. + /** Pointer to the current transfer buffer position. */
  4303. + uint8_t *xfer_buff;
  4304. + /** Total number of bytes to transfer. */
  4305. + uint32_t xfer_len;
  4306. + /** Number of bytes transferred so far. */
  4307. + uint32_t xfer_count;
  4308. + /** Packet count at start of transfer.*/
  4309. + uint16_t start_pkt_count;
  4310. +
  4311. + /**
  4312. + * Flag to indicate whether the transfer has been started. Set to 1 if
  4313. + * it has been started, 0 otherwise.
  4314. + */
  4315. + uint8_t xfer_started;
  4316. +
  4317. + /**
  4318. + * Set to 1 to indicate that a PING request should be issued on this
  4319. + * channel. If 0, process normally.
  4320. + */
  4321. + uint8_t do_ping;
  4322. +
  4323. + /**
  4324. + * Set to 1 to indicate that the error count for this transaction is
  4325. + * non-zero. Set to 0 if the error count is 0.
  4326. + */
  4327. + uint8_t error_state;
  4328. +
  4329. + /**
  4330. + * Set to 1 to indicate that this channel should be halted the next
  4331. + * time a request is queued for the channel. This is necessary in
  4332. + * slave mode if no request queue space is available when an attempt
  4333. + * is made to halt the channel.
  4334. + */
  4335. + uint8_t halt_on_queue;
  4336. +
  4337. + /**
  4338. + * Set to 1 if the host channel has been halted, but the core is not
  4339. + * finished flushing queued requests. Otherwise 0.
  4340. + */
  4341. + uint8_t halt_pending;
  4342. +
  4343. + /**
  4344. + * Reason for halting the host channel.
  4345. + */
  4346. + dwc_otg_halt_status_e halt_status;
  4347. +
  4348. + /*
  4349. + * Split settings for the host channel
  4350. + */
  4351. + uint8_t do_split; /**< Enable split for the channel */
  4352. + uint8_t complete_split; /**< Enable complete split */
  4353. + uint8_t hub_addr; /**< Address of high speed hub */
  4354. +
  4355. + uint8_t port_addr; /**< Port of the low/full speed device */
  4356. + /** Split transaction position
  4357. + * One of the following values:
  4358. + * - DWC_HCSPLIT_XACTPOS_MID
  4359. + * - DWC_HCSPLIT_XACTPOS_BEGIN
  4360. + * - DWC_HCSPLIT_XACTPOS_END
  4361. + * - DWC_HCSPLIT_XACTPOS_ALL */
  4362. + uint8_t xact_pos;
  4363. +
  4364. + /** Set when the host channel does a short read. */
  4365. + uint8_t short_read;
  4366. +
  4367. + /**
  4368. + * Number of requests issued for this channel since it was assigned to
  4369. + * the current transfer (not counting PINGs).
  4370. + */
  4371. + uint8_t requests;
  4372. +
  4373. + /**
  4374. + * Queue Head for the transfer being processed by this channel.
  4375. + */
  4376. + struct dwc_otg_qh *qh;
  4377. +
  4378. + /** @} */
  4379. +
  4380. + /** Entry in list of host channels. */
  4381. + struct list_head hc_list_entry;
  4382. +} dwc_hc_t;
  4383. +
  4384. +/**
  4385. + * The following parameters may be specified when starting the module. These
  4386. + * parameters define how the DWC_otg controller should be configured.
  4387. + * Parameter values are passed to the CIL initialization function
  4388. + * dwc_otg_cil_init.
  4389. + */
  4390. +
  4391. +typedef struct dwc_otg_core_params
  4392. +{
  4393. + int32_t opt;
  4394. +//#define dwc_param_opt_default 1
  4395. + /**
  4396. + * Specifies the OTG capabilities. The driver will automatically
  4397. + * detect the value for this parameter if none is specified.
  4398. + * 0 - HNP and SRP capable (default)
  4399. + * 1 - SRP Only capable
  4400. + * 2 - No HNP/SRP capable
  4401. + */
  4402. + int32_t otg_cap;
  4403. +#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0
  4404. +#define DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE 1
  4405. +#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2
  4406. +//#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE
  4407. + /**
  4408. + * Specifies whether to use slave or DMA mode for accessing the data
  4409. + * FIFOs. The driver will automatically detect the value for this
  4410. + * parameter if none is specified.
  4411. + * 0 - Slave
  4412. + * 1 - DMA (default, if available)
  4413. + */
  4414. + int32_t dma_enable;
  4415. +//#define dwc_param_dma_enable_default 1
  4416. + /** The DMA Burst size (applicable only for External DMA
  4417. + * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32)
  4418. + */
  4419. + int32_t dma_burst_size; /* Translate this to GAHBCFG values */
  4420. +//#define dwc_param_dma_burst_size_default 32
  4421. + /**
  4422. + * Specifies the maximum speed of operation in host and device mode.
  4423. + * The actual speed depends on the speed of the attached device and
  4424. + * the value of phy_type. The actual speed depends on the speed of the
  4425. + * attached device.
  4426. + * 0 - High Speed (default)
  4427. + * 1 - Full Speed
  4428. + */
  4429. + int32_t speed;
  4430. +//#define dwc_param_speed_default 0
  4431. +#define DWC_SPEED_PARAM_HIGH 0
  4432. +#define DWC_SPEED_PARAM_FULL 1
  4433. +
  4434. + /** Specifies whether low power mode is supported when attached
  4435. + * to a Full Speed or Low Speed device in host mode.
  4436. + * 0 - Don't support low power mode (default)
  4437. + * 1 - Support low power mode
  4438. + */
  4439. + int32_t host_support_fs_ls_low_power;
  4440. +//#define dwc_param_host_support_fs_ls_low_power_default 0
  4441. + /** Specifies the PHY clock rate in low power mode when connected to a
  4442. + * Low Speed device in host mode. This parameter is applicable only if
  4443. + * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS
  4444. + * then defaults to 6 MHZ otherwise 48 MHZ.
  4445. + *
  4446. + * 0 - 48 MHz
  4447. + * 1 - 6 MHz
  4448. + */
  4449. + int32_t host_ls_low_power_phy_clk;
  4450. +//#define dwc_param_host_ls_low_power_phy_clk_default 0
  4451. +#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0
  4452. +#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1
  4453. + /**
  4454. + * 0 - Use cC FIFO size parameters
  4455. + * 1 - Allow dynamic FIFO sizing (default)
  4456. + */
  4457. + int32_t enable_dynamic_fifo;
  4458. +//#define dwc_param_enable_dynamic_fifo_default 1
  4459. + /** Total number of 4-byte words in the data FIFO memory. This
  4460. + * memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic
  4461. + * Tx FIFOs.
  4462. + * 32 to 32768 (default 8192)
  4463. + * Note: The total FIFO memory depth in the FPGA configuration is 8192.
  4464. + */
  4465. + int32_t data_fifo_size;
  4466. +//#define dwc_param_data_fifo_size_default 8192
  4467. + /** Number of 4-byte words in the Rx FIFO in device mode when dynamic
  4468. + * FIFO sizing is enabled.
  4469. + * 16 to 32768 (default 1064)
  4470. + */
  4471. + int32_t dev_rx_fifo_size;
  4472. +//#define dwc_param_dev_rx_fifo_size_default 1064
  4473. + /** Number of 4-byte words in the non-periodic Tx FIFO in device mode
  4474. + * when dynamic FIFO sizing is enabled.
  4475. + * 16 to 32768 (default 1024)
  4476. + */
  4477. + int32_t dev_nperio_tx_fifo_size;
  4478. +//#define dwc_param_dev_nperio_tx_fifo_size_default 1024
  4479. + /** Number of 4-byte words in each of the periodic Tx FIFOs in device
  4480. + * mode when dynamic FIFO sizing is enabled.
  4481. + * 4 to 768 (default 256)
  4482. + */
  4483. + uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS];
  4484. +//#define dwc_param_dev_perio_tx_fifo_size_default 256
  4485. + /** Number of 4-byte words in the Rx FIFO in host mode when dynamic
  4486. + * FIFO sizing is enabled.
  4487. + * 16 to 32768 (default 1024)
  4488. + */
  4489. + int32_t host_rx_fifo_size;
  4490. +//#define dwc_param_host_rx_fifo_size_default 1024
  4491. + /** Number of 4-byte words in the non-periodic Tx FIFO in host mode
  4492. + * when Dynamic FIFO sizing is enabled in the core.
  4493. + * 16 to 32768 (default 1024)
  4494. + */
  4495. + int32_t host_nperio_tx_fifo_size;
  4496. +//#define dwc_param_host_nperio_tx_fifo_size_default 1024
  4497. + /** Number of 4-byte words in the host periodic Tx FIFO when dynamic
  4498. + * FIFO sizing is enabled.
  4499. + * 16 to 32768 (default 1024)
  4500. + */
  4501. + int32_t host_perio_tx_fifo_size;
  4502. +//#define dwc_param_host_perio_tx_fifo_size_default 1024
  4503. + /** The maximum transfer size supported in bytes.
  4504. + * 2047 to 65,535 (default 65,535)
  4505. + */
  4506. + int32_t max_transfer_size;
  4507. +//#define dwc_param_max_transfer_size_default 65535
  4508. + /** The maximum number of packets in a transfer.
  4509. + * 15 to 511 (default 511)
  4510. + */
  4511. + int32_t max_packet_count;
  4512. +//#define dwc_param_max_packet_count_default 511
  4513. + /** The number of host channel registers to use.
  4514. + * 1 to 16 (default 12)
  4515. + * Note: The FPGA configuration supports a maximum of 12 host channels.
  4516. + */
  4517. + int32_t host_channels;
  4518. +//#define dwc_param_host_channels_default 12
  4519. + /** The number of endpoints in addition to EP0 available for device
  4520. + * mode operations.
  4521. + * 1 to 15 (default 6 IN and OUT)
  4522. + * Note: The FPGA configuration supports a maximum of 6 IN and OUT
  4523. + * endpoints in addition to EP0.
  4524. + */
  4525. + int32_t dev_endpoints;
  4526. +//#define dwc_param_dev_endpoints_default 6
  4527. + /**
  4528. + * Specifies the type of PHY interface to use. By default, the driver
  4529. + * will automatically detect the phy_type.
  4530. + *
  4531. + * 0 - Full Speed PHY
  4532. + * 1 - UTMI+ (default)
  4533. + * 2 - ULPI
  4534. + */
  4535. + int32_t phy_type;
  4536. +#define DWC_PHY_TYPE_PARAM_FS 0
  4537. +#define DWC_PHY_TYPE_PARAM_UTMI 1
  4538. +#define DWC_PHY_TYPE_PARAM_ULPI 2
  4539. +//#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI
  4540. + /**
  4541. + * Specifies the UTMI+ Data Width. This parameter is
  4542. + * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI
  4543. + * PHY_TYPE, this parameter indicates the data width between
  4544. + * the MAC and the ULPI Wrapper.) Also, this parameter is
  4545. + * applicable only if the OTG_HSPHY_WIDTH cC parameter was set
  4546. + * to "8 and 16 bits", meaning that the core has been
  4547. + * configured to work at either data path width.
  4548. + *
  4549. + * 8 or 16 bits (default 16)
  4550. + */
  4551. + int32_t phy_utmi_width;
  4552. +//#define dwc_param_phy_utmi_width_default 16
  4553. + /**
  4554. + * Specifies whether the ULPI operates at double or single
  4555. + * data rate. This parameter is only applicable if PHY_TYPE is
  4556. + * ULPI.
  4557. + *
  4558. + * 0 - single data rate ULPI interface with 8 bit wide data
  4559. + * bus (default)
  4560. + * 1 - double data rate ULPI interface with 4 bit wide data
  4561. + * bus
  4562. + */
  4563. + int32_t phy_ulpi_ddr;
  4564. +//#define dwc_param_phy_ulpi_ddr_default 0
  4565. + /**
  4566. + * Specifies whether to use the internal or external supply to
  4567. + * drive the vbus with a ULPI phy.
  4568. + */
  4569. + int32_t phy_ulpi_ext_vbus;
  4570. +#define DWC_PHY_ULPI_INTERNAL_VBUS 0
  4571. +#define DWC_PHY_ULPI_EXTERNAL_VBUS 1
  4572. +//#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS
  4573. + /**
  4574. + * Specifies whether to use the I2Cinterface for full speed PHY. This
  4575. + * parameter is only applicable if PHY_TYPE is FS.
  4576. + * 0 - No (default)
  4577. + * 1 - Yes
  4578. + */
  4579. + int32_t i2c_enable;
  4580. +//#define dwc_param_i2c_enable_default 0
  4581. +
  4582. + int32_t ulpi_fs_ls;
  4583. +//#define dwc_param_ulpi_fs_ls_default 0
  4584. +
  4585. + int32_t ts_dline;
  4586. +//#define dwc_param_ts_dline_default 0
  4587. +
  4588. + /**
  4589. + * Specifies whether dedicated transmit FIFOs are
  4590. + * enabled for non periodic IN endpoints in device mode
  4591. + * 0 - No
  4592. + * 1 - Yes
  4593. + */
  4594. + int32_t en_multiple_tx_fifo;
  4595. +#define dwc_param_en_multiple_tx_fifo_default 1
  4596. +
  4597. + /** Number of 4-byte words in each of the Tx FIFOs in device
  4598. + * mode when dynamic FIFO sizing is enabled.
  4599. + * 4 to 768 (default 256)
  4600. + */
  4601. + uint32_t dev_tx_fifo_size[MAX_TX_FIFOS];
  4602. +#define dwc_param_dev_tx_fifo_size_default 256
  4603. +
  4604. + /** Thresholding enable flag-
  4605. + * bit 0 - enable non-ISO Tx thresholding
  4606. + * bit 1 - enable ISO Tx thresholding
  4607. + * bit 2 - enable Rx thresholding
  4608. + */
  4609. + uint32_t thr_ctl;
  4610. +#define dwc_param_thr_ctl_default 0
  4611. +
  4612. + /** Thresholding length for Tx
  4613. + * FIFOs in 32 bit DWORDs
  4614. + */
  4615. + uint32_t tx_thr_length;
  4616. +#define dwc_param_tx_thr_length_default 64
  4617. +
  4618. + /** Thresholding length for Rx
  4619. + * FIFOs in 32 bit DWORDs
  4620. + */
  4621. + uint32_t rx_thr_length;
  4622. +#define dwc_param_rx_thr_length_default 64
  4623. +} dwc_otg_core_params_t;
  4624. +
  4625. +#ifdef DEBUG
  4626. +struct dwc_otg_core_if;
  4627. +typedef struct hc_xfer_info
  4628. +{
  4629. + struct dwc_otg_core_if *core_if;
  4630. + dwc_hc_t *hc;
  4631. +} hc_xfer_info_t;
  4632. +#endif
  4633. +
  4634. +/**
  4635. + * The <code>dwc_otg_core_if</code> structure contains information needed to manage
  4636. + * the DWC_otg controller acting in either host or device mode. It
  4637. + * represents the programming view of the controller as a whole.
  4638. + */
  4639. +typedef struct dwc_otg_core_if
  4640. +{
  4641. + /** Parameters that define how the core should be configured.*/
  4642. + dwc_otg_core_params_t *core_params;
  4643. +
  4644. + /** Core Global registers starting at offset 000h. */
  4645. + dwc_otg_core_global_regs_t *core_global_regs;
  4646. +
  4647. + /** Device-specific information */
  4648. + dwc_otg_dev_if_t *dev_if;
  4649. + /** Host-specific information */
  4650. + dwc_otg_host_if_t *host_if;
  4651. +
  4652. + /*
  4653. + * Set to 1 if the core PHY interface bits in USBCFG have been
  4654. + * initialized.
  4655. + */
  4656. + uint8_t phy_init_done;
  4657. +
  4658. + /*
  4659. + * SRP Success flag, set by srp success interrupt in FS I2C mode
  4660. + */
  4661. + uint8_t srp_success;
  4662. + uint8_t srp_timer_started;
  4663. +
  4664. + /* Common configuration information */
  4665. + /** Power and Clock Gating Control Register */
  4666. + volatile uint32_t *pcgcctl;
  4667. +#define DWC_OTG_PCGCCTL_OFFSET 0xE00
  4668. +
  4669. + /** Push/pop addresses for endpoints or host channels.*/
  4670. + uint32_t *data_fifo[MAX_EPS_CHANNELS];
  4671. +#define DWC_OTG_DATA_FIFO_OFFSET 0x1000
  4672. +#define DWC_OTG_DATA_FIFO_SIZE 0x1000
  4673. +
  4674. + /** Total RAM for FIFOs (Bytes) */
  4675. + uint16_t total_fifo_size;
  4676. + /** Size of Rx FIFO (Bytes) */
  4677. + uint16_t rx_fifo_size;
  4678. + /** Size of Non-periodic Tx FIFO (Bytes) */
  4679. + uint16_t nperio_tx_fifo_size;
  4680. +
  4681. + /** 1 if DMA is enabled, 0 otherwise. */
  4682. + uint8_t dma_enable;
  4683. +
  4684. + /** 1 if dedicated Tx FIFOs are enabled, 0 otherwise. */
  4685. + uint8_t en_multiple_tx_fifo;
  4686. +
  4687. + /** Set to 1 if multiple packets of a high-bandwidth transfer is in
  4688. + * process of being queued */
  4689. + uint8_t queuing_high_bandwidth;
  4690. +
  4691. + /** Hardware Configuration -- stored here for convenience.*/
  4692. + hwcfg1_data_t hwcfg1;
  4693. + hwcfg2_data_t hwcfg2;
  4694. + hwcfg3_data_t hwcfg3;
  4695. + hwcfg4_data_t hwcfg4;
  4696. +
  4697. + /** The operational State, during transations
  4698. + * (a_host>>a_peripherial and b_device=>b_host) this may not
  4699. + * match the core but allows the software to determine
  4700. + * transitions.
  4701. + */
  4702. + uint8_t op_state;
  4703. +
  4704. + /**
  4705. + * Set to 1 if the HCD needs to be restarted on a session request
  4706. + * interrupt. This is required if no connector ID status change has
  4707. + * occurred since the HCD was last disconnected.
  4708. + */
  4709. + uint8_t restart_hcd_on_session_req;
  4710. +
  4711. + /** HCD callbacks */
  4712. + /** A-Device is a_host */
  4713. +#define A_HOST (1)
  4714. + /** A-Device is a_suspend */
  4715. +#define A_SUSPEND (2)
  4716. + /** A-Device is a_peripherial */
  4717. +#define A_PERIPHERAL (3)
  4718. + /** B-Device is operating as a Peripheral. */
  4719. +#define B_PERIPHERAL (4)
  4720. + /** B-Device is operating as a Host. */
  4721. +#define B_HOST (5)
  4722. +
  4723. + /** HCD callbacks */
  4724. + struct dwc_otg_cil_callbacks *hcd_cb;
  4725. + /** PCD callbacks */
  4726. + struct dwc_otg_cil_callbacks *pcd_cb;
  4727. +
  4728. + /** Device mode Periodic Tx FIFO Mask */
  4729. + uint32_t p_tx_msk;
  4730. + /** Device mode Periodic Tx FIFO Mask */
  4731. + uint32_t tx_msk;
  4732. +
  4733. +#ifdef DEBUG
  4734. + uint32_t start_hcchar_val[MAX_EPS_CHANNELS];
  4735. +
  4736. + hc_xfer_info_t hc_xfer_info[MAX_EPS_CHANNELS];
  4737. + struct timer_list hc_xfer_timer[MAX_EPS_CHANNELS];
  4738. +
  4739. +#if 1 // winder
  4740. + uint32_t hfnum_7_samples;
  4741. + uint32_t hfnum_7_frrem_accum;
  4742. + uint32_t hfnum_0_samples;
  4743. + uint32_t hfnum_0_frrem_accum;
  4744. + uint32_t hfnum_other_samples;
  4745. + uint32_t hfnum_other_frrem_accum;
  4746. +#else
  4747. + uint32_t hfnum_7_samples;
  4748. + uint64_t hfnum_7_frrem_accum;
  4749. + uint32_t hfnum_0_samples;
  4750. + uint64_t hfnum_0_frrem_accum;
  4751. + uint32_t hfnum_other_samples;
  4752. + uint64_t hfnum_other_frrem_accum;
  4753. +#endif
  4754. + resource_size_t phys_addr; /* Added to support PLB DMA : phys-virt mapping */
  4755. +#endif
  4756. +
  4757. +} dwc_otg_core_if_t;
  4758. +
  4759. +/*
  4760. + * The following functions support initialization of the CIL driver component
  4761. + * and the DWC_otg controller.
  4762. + */
  4763. +extern dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t *_reg_base_addr,
  4764. + dwc_otg_core_params_t *_core_params);
  4765. +extern void dwc_otg_cil_remove(dwc_otg_core_if_t *_core_if);
  4766. +extern void dwc_otg_core_init(dwc_otg_core_if_t *_core_if);
  4767. +extern void dwc_otg_core_host_init(dwc_otg_core_if_t *_core_if);
  4768. +extern void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if);
  4769. +extern void dwc_otg_enable_global_interrupts( dwc_otg_core_if_t *_core_if );
  4770. +extern void dwc_otg_disable_global_interrupts( dwc_otg_core_if_t *_core_if );
  4771. +
  4772. +/** @name Device CIL Functions
  4773. + * The following functions support managing the DWC_otg controller in device
  4774. + * mode.
  4775. + */
  4776. +/**@{*/
  4777. +extern void dwc_otg_wakeup(dwc_otg_core_if_t *_core_if);
  4778. +extern void dwc_otg_read_setup_packet (dwc_otg_core_if_t *_core_if, uint32_t *_dest);
  4779. +extern uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t *_core_if);
  4780. +extern void dwc_otg_ep0_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
  4781. +extern void dwc_otg_ep_activate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
  4782. +extern void dwc_otg_ep_deactivate(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
  4783. +extern void dwc_otg_ep_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
  4784. +extern void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
  4785. +extern void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
  4786. +extern void dwc_otg_ep_write_packet(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep, int _dma);
  4787. +extern void dwc_otg_ep_set_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
  4788. +extern void dwc_otg_ep_clear_stall(dwc_otg_core_if_t *_core_if, dwc_ep_t *_ep);
  4789. +extern void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t *_core_if);
  4790. +extern void dwc_otg_dump_dev_registers(dwc_otg_core_if_t *_core_if);
  4791. +/**@}*/
  4792. +
  4793. +/** @name Host CIL Functions
  4794. + * The following functions support managing the DWC_otg controller in host
  4795. + * mode.
  4796. + */
  4797. +/**@{*/
  4798. +extern void dwc_otg_hc_init(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
  4799. +extern void dwc_otg_hc_halt(dwc_otg_core_if_t *_core_if,
  4800. + dwc_hc_t *_hc,
  4801. + dwc_otg_halt_status_e _halt_status);
  4802. +extern void dwc_otg_hc_cleanup(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
  4803. +extern void dwc_otg_hc_start_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
  4804. +extern int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
  4805. +extern void dwc_otg_hc_do_ping(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
  4806. +extern void dwc_otg_hc_write_packet(dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc);
  4807. +extern void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t *_core_if);
  4808. +extern void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t *_core_if);
  4809. +
  4810. +/**
  4811. + * This function Reads HPRT0 in preparation to modify. It keeps the
  4812. + * WC bits 0 so that if they are read as 1, they won't clear when you
  4813. + * write it back
  4814. + */
  4815. +static inline uint32_t dwc_otg_read_hprt0(dwc_otg_core_if_t *_core_if)
  4816. +{
  4817. + hprt0_data_t hprt0;
  4818. + hprt0.d32 = dwc_read_reg32(_core_if->host_if->hprt0);
  4819. + hprt0.b.prtena = 0;
  4820. + hprt0.b.prtconndet = 0;
  4821. + hprt0.b.prtenchng = 0;
  4822. + hprt0.b.prtovrcurrchng = 0;
  4823. + return hprt0.d32;
  4824. +}
  4825. +
  4826. +extern void dwc_otg_dump_host_registers(dwc_otg_core_if_t *_core_if);
  4827. +/**@}*/
  4828. +
  4829. +/** @name Common CIL Functions
  4830. + * The following functions support managing the DWC_otg controller in either
  4831. + * device or host mode.
  4832. + */
  4833. +/**@{*/
  4834. +
  4835. +extern void dwc_otg_read_packet(dwc_otg_core_if_t *core_if,
  4836. + uint8_t *dest,
  4837. + uint16_t bytes);
  4838. +
  4839. +extern void dwc_otg_dump_global_registers(dwc_otg_core_if_t *_core_if);
  4840. +
  4841. +extern void dwc_otg_flush_tx_fifo( dwc_otg_core_if_t *_core_if,
  4842. + const int _num );
  4843. +extern void dwc_otg_flush_rx_fifo( dwc_otg_core_if_t *_core_if );
  4844. +extern void dwc_otg_core_reset( dwc_otg_core_if_t *_core_if );
  4845. +
  4846. +#define NP_TXFIFO_EMPTY -1
  4847. +#define MAX_NP_TXREQUEST_Q_SLOTS 8
  4848. +/**
  4849. + * This function returns the endpoint number of the request at
  4850. + * the top of non-periodic TX FIFO, or -1 if the request FIFO is
  4851. + * empty.
  4852. + */
  4853. +static inline int dwc_otg_top_nptxfifo_epnum(dwc_otg_core_if_t *_core_if) {
  4854. + gnptxsts_data_t txstatus = {.d32 = 0};
  4855. +
  4856. + txstatus.d32 = dwc_read_reg32(&_core_if->core_global_regs->gnptxsts);
  4857. + return (txstatus.b.nptxqspcavail == MAX_NP_TXREQUEST_Q_SLOTS ?
  4858. + -1 : txstatus.b.nptxqtop_chnep);
  4859. +}
  4860. +/**
  4861. + * This function returns the Core Interrupt register.
  4862. + */
  4863. +static inline uint32_t dwc_otg_read_core_intr(dwc_otg_core_if_t *_core_if) {
  4864. + return (dwc_read_reg32(&_core_if->core_global_regs->gintsts) &
  4865. + dwc_read_reg32(&_core_if->core_global_regs->gintmsk));
  4866. +}
  4867. +
  4868. +/**
  4869. + * This function returns the OTG Interrupt register.
  4870. + */
  4871. +static inline uint32_t dwc_otg_read_otg_intr (dwc_otg_core_if_t *_core_if) {
  4872. + return (dwc_read_reg32 (&_core_if->core_global_regs->gotgint));
  4873. +}
  4874. +
  4875. +/**
  4876. + * This function reads the Device All Endpoints Interrupt register and
  4877. + * returns the IN endpoint interrupt bits.
  4878. + */
  4879. +static inline uint32_t dwc_otg_read_dev_all_in_ep_intr(dwc_otg_core_if_t *_core_if) {
  4880. + uint32_t v;
  4881. + v = dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daint) &
  4882. + dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daintmsk);
  4883. + return (v & 0xffff);
  4884. +
  4885. +}
  4886. +
  4887. +/**
  4888. + * This function reads the Device All Endpoints Interrupt register and
  4889. + * returns the OUT endpoint interrupt bits.
  4890. + */
  4891. +static inline uint32_t dwc_otg_read_dev_all_out_ep_intr(dwc_otg_core_if_t *_core_if) {
  4892. + uint32_t v;
  4893. + v = dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daint) &
  4894. + dwc_read_reg32(&_core_if->dev_if->dev_global_regs->daintmsk);
  4895. + return ((v & 0xffff0000) >> 16);
  4896. +}
  4897. +
  4898. +/**
  4899. + * This function returns the Device IN EP Interrupt register
  4900. + */
  4901. +static inline uint32_t dwc_otg_read_dev_in_ep_intr(dwc_otg_core_if_t *_core_if,
  4902. + dwc_ep_t *_ep)
  4903. +{
  4904. + dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
  4905. + uint32_t v, msk, emp;
  4906. + msk = dwc_read_reg32(&dev_if->dev_global_regs->diepmsk);
  4907. + emp = dwc_read_reg32(&dev_if->dev_global_regs->dtknqr4_fifoemptymsk);
  4908. + msk |= ((emp >> _ep->num) & 0x1) << 7;
  4909. + v = dwc_read_reg32(&dev_if->in_ep_regs[_ep->num]->diepint) & msk;
  4910. +/*
  4911. + dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
  4912. + uint32_t v;
  4913. + v = dwc_read_reg32(&dev_if->in_ep_regs[_ep->num]->diepint) &
  4914. + dwc_read_reg32(&dev_if->dev_global_regs->diepmsk);
  4915. +*/
  4916. + return v;
  4917. +}
  4918. +/**
  4919. + * This function returns the Device OUT EP Interrupt register
  4920. + */
  4921. +static inline uint32_t dwc_otg_read_dev_out_ep_intr(dwc_otg_core_if_t *_core_if,
  4922. + dwc_ep_t *_ep)
  4923. +{
  4924. + dwc_otg_dev_if_t *dev_if = _core_if->dev_if;
  4925. + uint32_t v;
  4926. + v = dwc_read_reg32( &dev_if->out_ep_regs[_ep->num]->doepint) &
  4927. + dwc_read_reg32(&dev_if->dev_global_regs->doepmsk);
  4928. + return v;
  4929. +}
  4930. +
  4931. +/**
  4932. + * This function returns the Host All Channel Interrupt register
  4933. + */
  4934. +static inline uint32_t dwc_otg_read_host_all_channels_intr (dwc_otg_core_if_t *_core_if)
  4935. +{
  4936. + return (dwc_read_reg32 (&_core_if->host_if->host_global_regs->haint));
  4937. +}
  4938. +
  4939. +static inline uint32_t dwc_otg_read_host_channel_intr (dwc_otg_core_if_t *_core_if, dwc_hc_t *_hc)
  4940. +{
  4941. + return (dwc_read_reg32 (&_core_if->host_if->hc_regs[_hc->hc_num]->hcint));
  4942. +}
  4943. +
  4944. +
  4945. +/**
  4946. + * This function returns the mode of the operation, host or device.
  4947. + *
  4948. + * @return 0 - Device Mode, 1 - Host Mode
  4949. + */
  4950. +static inline uint32_t dwc_otg_mode(dwc_otg_core_if_t *_core_if) {
  4951. + return (dwc_read_reg32( &_core_if->core_global_regs->gintsts ) & 0x1);
  4952. +}
  4953. +
  4954. +static inline uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t *_core_if)
  4955. +{
  4956. + return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
  4957. +}
  4958. +static inline uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t *_core_if)
  4959. +{
  4960. + return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
  4961. +}
  4962. +
  4963. +extern int32_t dwc_otg_handle_common_intr( dwc_otg_core_if_t *_core_if );
  4964. +
  4965. +
  4966. +/**@}*/
  4967. +
  4968. +/**
  4969. + * DWC_otg CIL callback structure. This structure allows the HCD and
  4970. + * PCD to register functions used for starting and stopping the PCD
  4971. + * and HCD for role change on for a DRD.
  4972. + */
  4973. +typedef struct dwc_otg_cil_callbacks
  4974. +{
  4975. + /** Start function for role change */
  4976. + int (*start) (void *_p);
  4977. + /** Stop Function for role change */
  4978. + int (*stop) (void *_p);
  4979. + /** Disconnect Function for role change */
  4980. + int (*disconnect) (void *_p);
  4981. + /** Resume/Remote wakeup Function */
  4982. + int (*resume_wakeup) (void *_p);
  4983. + /** Suspend function */
  4984. + int (*suspend) (void *_p);
  4985. + /** Session Start (SRP) */
  4986. + int (*session_start) (void *_p);
  4987. + /** Pointer passed to start() and stop() */
  4988. + void *p;
  4989. +} dwc_otg_cil_callbacks_t;
  4990. +
  4991. +
  4992. +
  4993. +extern void dwc_otg_cil_register_pcd_callbacks( dwc_otg_core_if_t *_core_if,
  4994. + dwc_otg_cil_callbacks_t *_cb,
  4995. + void *_p);
  4996. +extern void dwc_otg_cil_register_hcd_callbacks( dwc_otg_core_if_t *_core_if,
  4997. + dwc_otg_cil_callbacks_t *_cb,
  4998. + void *_p);
  4999. +
  5000. +
  5001. +#endif
  5002. diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h b/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h
  5003. new file mode 100644
  5004. index 0000000..b0298ec
  5005. --- /dev/null
  5006. +++ b/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h
  5007. @@ -0,0 +1,58 @@
  5008. +/******************************************************************************
  5009. +**
  5010. +** FILE NAME : dwc_otg_cil_ifx.h
  5011. +** PROJECT : Twinpass/Danube
  5012. +** MODULES : DWC OTG USB
  5013. +**
  5014. +** DATE : 07 Sep. 2007
  5015. +** AUTHOR : Sung Winder
  5016. +** DESCRIPTION : Default param value.
  5017. +** COPYRIGHT : Copyright (c) 2007
  5018. +** Infineon Technologies AG
  5019. +** 2F, No.2, Li-Hsin Rd., Hsinchu Science Park,
  5020. +** Hsin-chu City, 300 Taiwan.
  5021. +**
  5022. +** This program is free software; you can redistribute it and/or modify
  5023. +** it under the terms of the GNU General Public License as published by
  5024. +** the Free Software Foundation; either version 2 of the License, or
  5025. +** (at your option) any later version.
  5026. +**
  5027. +** HISTORY
  5028. +** $Date $Author $Comment
  5029. +** 12 April 2007 Sung Winder Initiate Version
  5030. +*******************************************************************************/
  5031. +#if !defined(__DWC_OTG_CIL_IFX_H__)
  5032. +#define __DWC_OTG_CIL_IFX_H__
  5033. +
  5034. +/* ================ Default param value ================== */
  5035. +#define dwc_param_opt_default 1
  5036. +#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE
  5037. +#define dwc_param_dma_enable_default 1
  5038. +#define dwc_param_dma_burst_size_default 32
  5039. +#define dwc_param_speed_default DWC_SPEED_PARAM_HIGH
  5040. +#define dwc_param_host_support_fs_ls_low_power_default 0
  5041. +#define dwc_param_host_ls_low_power_phy_clk_default DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ
  5042. +#define dwc_param_enable_dynamic_fifo_default 1
  5043. +#define dwc_param_data_fifo_size_default 2048
  5044. +#define dwc_param_dev_rx_fifo_size_default 1024
  5045. +#define dwc_param_dev_nperio_tx_fifo_size_default 1024
  5046. +#define dwc_param_dev_perio_tx_fifo_size_default 768
  5047. +#define dwc_param_host_rx_fifo_size_default 640
  5048. +#define dwc_param_host_nperio_tx_fifo_size_default 640
  5049. +#define dwc_param_host_perio_tx_fifo_size_default 768
  5050. +#define dwc_param_max_transfer_size_default 65535
  5051. +#define dwc_param_max_packet_count_default 511
  5052. +#define dwc_param_host_channels_default 16
  5053. +#define dwc_param_dev_endpoints_default 6
  5054. +#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI
  5055. +#define dwc_param_phy_utmi_width_default 16
  5056. +#define dwc_param_phy_ulpi_ddr_default 0
  5057. +#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS
  5058. +#define dwc_param_i2c_enable_default 0
  5059. +#define dwc_param_ulpi_fs_ls_default 0
  5060. +#define dwc_param_ts_dline_default 0
  5061. +
  5062. +/* ======================================================= */
  5063. +
  5064. +#endif // __DWC_OTG_CIL_IFX_H__
  5065. +
  5066. diff --git a/drivers/usb/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c
  5067. new file mode 100644
  5068. index 0000000..d469ab4
  5069. --- /dev/null
  5070. +++ b/drivers/usb/dwc_otg/dwc_otg_cil_intr.c
  5071. @@ -0,0 +1,708 @@
  5072. +/* ==========================================================================
  5073. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_cil_intr.c $
  5074. + * $Revision: 1.1.1.1 $
  5075. + * $Date: 2009-04-17 06:15:34 $
  5076. + * $Change: 553126 $
  5077. + *
  5078. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  5079. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  5080. + * otherwise expressly agreed to in writing between Synopsys and you.
  5081. + *
  5082. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  5083. + * any End User Software License Agreement or Agreement for Licensed Product
  5084. + * with Synopsys or any supplement thereto. You are permitted to use and
  5085. + * redistribute this Software in source and binary forms, with or without
  5086. + * modification, provided that redistributions of source code must retain this
  5087. + * notice. You may not view, use, disclose, copy or distribute this file or
  5088. + * any information contained herein except pursuant to this license grant from
  5089. + * Synopsys. If you do not agree with this notice, including the disclaimer
  5090. + * below, then you are not authorized to use the Software.
  5091. + *
  5092. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  5093. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  5094. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  5095. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  5096. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  5097. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  5098. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  5099. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  5100. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  5101. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  5102. + * DAMAGE.
  5103. + * ========================================================================== */
  5104. +
  5105. +/** @file
  5106. + *
  5107. + * The Core Interface Layer provides basic services for accessing and
  5108. + * managing the DWC_otg hardware. These services are used by both the
  5109. + * Host Controller Driver and the Peripheral Controller Driver.
  5110. + *
  5111. + * This file contains the Common Interrupt handlers.
  5112. + */
  5113. +#include "dwc_otg_plat.h"
  5114. +#include "dwc_otg_regs.h"
  5115. +#include "dwc_otg_cil.h"
  5116. +
  5117. +#ifdef DEBUG
  5118. +inline const char *op_state_str( dwc_otg_core_if_t *_core_if )
  5119. +{
  5120. + return (_core_if->op_state==A_HOST?"a_host":
  5121. + (_core_if->op_state==A_SUSPEND?"a_suspend":
  5122. + (_core_if->op_state==A_PERIPHERAL?"a_peripheral":
  5123. + (_core_if->op_state==B_PERIPHERAL?"b_peripheral":
  5124. + (_core_if->op_state==B_HOST?"b_host":
  5125. + "unknown")))));
  5126. +}
  5127. +#endif
  5128. +
  5129. +/** This function will log a debug message
  5130. + *
  5131. + * @param _core_if Programming view of DWC_otg controller.
  5132. + */
  5133. +int32_t dwc_otg_handle_mode_mismatch_intr (dwc_otg_core_if_t *_core_if)
  5134. +{
  5135. + gintsts_data_t gintsts;
  5136. + DWC_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
  5137. + dwc_otg_mode(_core_if) ? "Host" : "Device");
  5138. +
  5139. + /* Clear interrupt */
  5140. + gintsts.d32 = 0;
  5141. + gintsts.b.modemismatch = 1;
  5142. + dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
  5143. + return 1;
  5144. +}
  5145. +
  5146. +/** Start the HCD. Helper function for using the HCD callbacks.
  5147. + *
  5148. + * @param _core_if Programming view of DWC_otg controller.
  5149. + */
  5150. +static inline void hcd_start( dwc_otg_core_if_t *_core_if )
  5151. +{
  5152. + if (_core_if->hcd_cb && _core_if->hcd_cb->start) {
  5153. + _core_if->hcd_cb->start( _core_if->hcd_cb->p );
  5154. + }
  5155. +}
  5156. +/** Stop the HCD. Helper function for using the HCD callbacks.
  5157. + *
  5158. + * @param _core_if Programming view of DWC_otg controller.
  5159. + */
  5160. +static inline void hcd_stop( dwc_otg_core_if_t *_core_if )
  5161. +{
  5162. + if (_core_if->hcd_cb && _core_if->hcd_cb->stop) {
  5163. + _core_if->hcd_cb->stop( _core_if->hcd_cb->p );
  5164. + }
  5165. +}
  5166. +/** Disconnect the HCD. Helper function for using the HCD callbacks.
  5167. + *
  5168. + * @param _core_if Programming view of DWC_otg controller.
  5169. + */
  5170. +static inline void hcd_disconnect( dwc_otg_core_if_t *_core_if )
  5171. +{
  5172. + if (_core_if->hcd_cb && _core_if->hcd_cb->disconnect) {
  5173. + _core_if->hcd_cb->disconnect( _core_if->hcd_cb->p );
  5174. + }
  5175. +}
  5176. +/** Inform the HCD the a New Session has begun. Helper function for
  5177. + * using the HCD callbacks.
  5178. + *
  5179. + * @param _core_if Programming view of DWC_otg controller.
  5180. + */
  5181. +static inline void hcd_session_start( dwc_otg_core_if_t *_core_if )
  5182. +{
  5183. + if (_core_if->hcd_cb && _core_if->hcd_cb->session_start) {
  5184. + _core_if->hcd_cb->session_start( _core_if->hcd_cb->p );
  5185. + }
  5186. +}
  5187. +
  5188. +/** Start the PCD. Helper function for using the PCD callbacks.
  5189. + *
  5190. + * @param _core_if Programming view of DWC_otg controller.
  5191. + */
  5192. +static inline void pcd_start( dwc_otg_core_if_t *_core_if )
  5193. +{
  5194. + if (_core_if->pcd_cb && _core_if->pcd_cb->start ) {
  5195. + _core_if->pcd_cb->start( _core_if->pcd_cb->p );
  5196. + }
  5197. +}
  5198. +/** Stop the PCD. Helper function for using the PCD callbacks.
  5199. + *
  5200. + * @param _core_if Programming view of DWC_otg controller.
  5201. + */
  5202. +static inline void pcd_stop( dwc_otg_core_if_t *_core_if )
  5203. +{
  5204. + if (_core_if->pcd_cb && _core_if->pcd_cb->stop ) {
  5205. + _core_if->pcd_cb->stop( _core_if->pcd_cb->p );
  5206. + }
  5207. +}
  5208. +/** Suspend the PCD. Helper function for using the PCD callbacks.
  5209. + *
  5210. + * @param _core_if Programming view of DWC_otg controller.
  5211. + */
  5212. +static inline void pcd_suspend( dwc_otg_core_if_t *_core_if )
  5213. +{
  5214. + if (_core_if->pcd_cb && _core_if->pcd_cb->suspend ) {
  5215. + _core_if->pcd_cb->suspend( _core_if->pcd_cb->p );
  5216. + }
  5217. +}
  5218. +/** Resume the PCD. Helper function for using the PCD callbacks.
  5219. + *
  5220. + * @param _core_if Programming view of DWC_otg controller.
  5221. + */
  5222. +static inline void pcd_resume( dwc_otg_core_if_t *_core_if )
  5223. +{
  5224. + if (_core_if->pcd_cb && _core_if->pcd_cb->resume_wakeup ) {
  5225. + _core_if->pcd_cb->resume_wakeup( _core_if->pcd_cb->p );
  5226. + }
  5227. +}
  5228. +
  5229. +/**
  5230. + * This function handles the OTG Interrupts. It reads the OTG
  5231. + * Interrupt Register (GOTGINT) to determine what interrupt has
  5232. + * occurred.
  5233. + *
  5234. + * @param _core_if Programming view of DWC_otg controller.
  5235. + */
  5236. +int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t *_core_if)
  5237. +{
  5238. + dwc_otg_core_global_regs_t *global_regs =
  5239. + _core_if->core_global_regs;
  5240. + gotgint_data_t gotgint;
  5241. + gotgctl_data_t gotgctl;
  5242. + gintmsk_data_t gintmsk;
  5243. +
  5244. + gotgint.d32 = dwc_read_reg32( &global_regs->gotgint);
  5245. + gotgctl.d32 = dwc_read_reg32( &global_regs->gotgctl);
  5246. + DWC_DEBUGPL(DBG_CIL, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint.d32,
  5247. + op_state_str(_core_if));
  5248. + //DWC_DEBUGPL(DBG_CIL, "gotgctl=%08x\n", gotgctl.d32 );
  5249. +
  5250. + if (gotgint.b.sesenddet) {
  5251. + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
  5252. + "Session End Detected++ (%s)\n",
  5253. + op_state_str(_core_if));
  5254. + gotgctl.d32 = dwc_read_reg32( &global_regs->gotgctl);
  5255. +
  5256. + if (_core_if->op_state == B_HOST) {
  5257. + pcd_start( _core_if );
  5258. + _core_if->op_state = B_PERIPHERAL;
  5259. + } else {
  5260. + /* If not B_HOST and Device HNP still set. HNP
  5261. + * Did not succeed!*/
  5262. + if (gotgctl.b.devhnpen) {
  5263. + DWC_DEBUGPL(DBG_ANY, "Session End Detected\n");
  5264. + DWC_ERROR( "Device Not Connected/Responding!\n" );
  5265. + }
  5266. +
  5267. + /* If Session End Detected the B-Cable has
  5268. + * been disconnected. */
  5269. + /* Reset PCD and Gadget driver to a
  5270. + * clean state. */
  5271. + pcd_stop(_core_if);
  5272. + }
  5273. + gotgctl.d32 = 0;
  5274. + gotgctl.b.devhnpen = 1;
  5275. + dwc_modify_reg32( &global_regs->gotgctl,
  5276. + gotgctl.d32, 0);
  5277. + }
  5278. + if (gotgint.b.sesreqsucstschng) {
  5279. + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
  5280. + "Session Reqeust Success Status Change++\n");
  5281. + gotgctl.d32 = dwc_read_reg32( &global_regs->gotgctl);
  5282. + if (gotgctl.b.sesreqscs) {
  5283. + if ((_core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) &&
  5284. + (_core_if->core_params->i2c_enable)) {
  5285. + _core_if->srp_success = 1;
  5286. + }
  5287. + else {
  5288. + pcd_resume( _core_if );
  5289. + /* Clear Session Request */
  5290. + gotgctl.d32 = 0;
  5291. + gotgctl.b.sesreq = 1;
  5292. + dwc_modify_reg32( &global_regs->gotgctl,
  5293. + gotgctl.d32, 0);
  5294. + }
  5295. + }
  5296. + }
  5297. + if (gotgint.b.hstnegsucstschng) {
  5298. + /* Print statements during the HNP interrupt handling
  5299. + * can cause it to fail.*/
  5300. + gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl);
  5301. + if (gotgctl.b.hstnegscs) {
  5302. + if (dwc_otg_is_host_mode(_core_if) ) {
  5303. + _core_if->op_state = B_HOST;
  5304. + /*
  5305. + * Need to disable SOF interrupt immediately.
  5306. + * When switching from device to host, the PCD
  5307. + * interrupt handler won't handle the
  5308. + * interrupt if host mode is already set. The
  5309. + * HCD interrupt handler won't get called if
  5310. + * the HCD state is HALT. This means that the
  5311. + * interrupt does not get handled and Linux
  5312. + * complains loudly.
  5313. + */
  5314. + gintmsk.d32 = 0;
  5315. + gintmsk.b.sofintr = 1;
  5316. + dwc_modify_reg32(&global_regs->gintmsk,
  5317. + gintmsk.d32, 0);
  5318. + pcd_stop(_core_if);
  5319. + /*
  5320. + * Initialize the Core for Host mode.
  5321. + */
  5322. + hcd_start( _core_if );
  5323. + _core_if->op_state = B_HOST;
  5324. + }
  5325. + } else {
  5326. + gotgctl.d32 = 0;
  5327. + gotgctl.b.hnpreq = 1;
  5328. + gotgctl.b.devhnpen = 1;
  5329. + dwc_modify_reg32( &global_regs->gotgctl,
  5330. + gotgctl.d32, 0);
  5331. + DWC_DEBUGPL( DBG_ANY, "HNP Failed\n");
  5332. + DWC_ERROR( "Device Not Connected/Responding\n" );
  5333. + }
  5334. + }
  5335. + if (gotgint.b.hstnegdet) {
  5336. + /* The disconnect interrupt is set at the same time as
  5337. + * Host Negotiation Detected. During the mode
  5338. + * switch all interrupts are cleared so the disconnect
  5339. + * interrupt handler will not get executed.
  5340. + */
  5341. + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
  5342. + "Host Negotiation Detected++ (%s)\n",
  5343. + (dwc_otg_is_host_mode(_core_if)?"Host":"Device"));
  5344. + if (dwc_otg_is_device_mode(_core_if)){
  5345. + DWC_DEBUGPL(DBG_ANY, "a_suspend->a_peripheral (%d)\n",_core_if->op_state);
  5346. + hcd_disconnect( _core_if );
  5347. + pcd_start( _core_if );
  5348. + _core_if->op_state = A_PERIPHERAL;
  5349. + } else {
  5350. + /*
  5351. + * Need to disable SOF interrupt immediately. When
  5352. + * switching from device to host, the PCD interrupt
  5353. + * handler won't handle the interrupt if host mode is
  5354. + * already set. The HCD interrupt handler won't get
  5355. + * called if the HCD state is HALT. This means that
  5356. + * the interrupt does not get handled and Linux
  5357. + * complains loudly.
  5358. + */
  5359. + gintmsk.d32 = 0;
  5360. + gintmsk.b.sofintr = 1;
  5361. + dwc_modify_reg32(&global_regs->gintmsk,
  5362. + gintmsk.d32, 0);
  5363. + pcd_stop( _core_if );
  5364. + hcd_start( _core_if );
  5365. + _core_if->op_state = A_HOST;
  5366. + }
  5367. + }
  5368. + if (gotgint.b.adevtoutchng) {
  5369. + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
  5370. + "A-Device Timeout Change++\n");
  5371. + }
  5372. + if (gotgint.b.debdone) {
  5373. + DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
  5374. + "Debounce Done++\n");
  5375. + }
  5376. +
  5377. + /* Clear GOTGINT */
  5378. + dwc_write_reg32 (&_core_if->core_global_regs->gotgint, gotgint.d32);
  5379. +
  5380. + return 1;
  5381. +}
  5382. +
  5383. +/**
  5384. + * This function handles the Connector ID Status Change Interrupt. It
  5385. + * reads the OTG Interrupt Register (GOTCTL) to determine whether this
  5386. + * is a Device to Host Mode transition or a Host Mode to Device
  5387. + * Transition.
  5388. + *
  5389. + * This only occurs when the cable is connected/removed from the PHY
  5390. + * connector.
  5391. + *
  5392. + * @param _core_if Programming view of DWC_otg controller.
  5393. + */
  5394. +int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t *_core_if)
  5395. +{
  5396. + uint32_t count = 0;
  5397. +
  5398. + gintsts_data_t gintsts = { .d32 = 0 };
  5399. + gintmsk_data_t gintmsk = { .d32 = 0 };
  5400. + gotgctl_data_t gotgctl = { .d32 = 0 };
  5401. +
  5402. + /*
  5403. + * Need to disable SOF interrupt immediately. If switching from device
  5404. + * to host, the PCD interrupt handler won't handle the interrupt if
  5405. + * host mode is already set. The HCD interrupt handler won't get
  5406. + * called if the HCD state is HALT. This means that the interrupt does
  5407. + * not get handled and Linux complains loudly.
  5408. + */
  5409. + gintmsk.b.sofintr = 1;
  5410. + dwc_modify_reg32(&_core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
  5411. +
  5412. + DWC_DEBUGPL(DBG_CIL, " ++Connector ID Status Change Interrupt++ (%s)\n",
  5413. + (dwc_otg_is_host_mode(_core_if)?"Host":"Device"));
  5414. + gotgctl.d32 = dwc_read_reg32(&_core_if->core_global_regs->gotgctl);
  5415. + DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32);
  5416. + DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts);
  5417. +
  5418. + /* B-Device connector (Device Mode) */
  5419. + if (gotgctl.b.conidsts) {
  5420. + /* Wait for switch to device mode. */
  5421. + while (!dwc_otg_is_device_mode(_core_if) ){
  5422. + DWC_PRINT("Waiting for Peripheral Mode, Mode=%s\n",
  5423. + (dwc_otg_is_host_mode(_core_if)?"Host":"Peripheral"));
  5424. + MDELAY(100);
  5425. + if (++count > 10000) *(uint32_t*)NULL=0;
  5426. + }
  5427. + _core_if->op_state = B_PERIPHERAL;
  5428. + dwc_otg_core_init(_core_if);
  5429. + dwc_otg_enable_global_interrupts(_core_if);
  5430. + pcd_start( _core_if );
  5431. + } else {
  5432. + /* A-Device connector (Host Mode) */
  5433. + while (!dwc_otg_is_host_mode(_core_if) ) {
  5434. + DWC_PRINT("Waiting for Host Mode, Mode=%s\n",
  5435. + (dwc_otg_is_host_mode(_core_if)?"Host":"Peripheral"));
  5436. + MDELAY(100);
  5437. + if (++count > 10000) *(uint32_t*)NULL=0;
  5438. + }
  5439. + _core_if->op_state = A_HOST;
  5440. + /*
  5441. + * Initialize the Core for Host mode.
  5442. + */
  5443. + dwc_otg_core_init(_core_if);
  5444. + dwc_otg_enable_global_interrupts(_core_if);
  5445. + hcd_start( _core_if );
  5446. + }
  5447. +
  5448. + /* Set flag and clear interrupt */
  5449. + gintsts.b.conidstschng = 1;
  5450. + dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
  5451. +
  5452. + return 1;
  5453. +}
  5454. +
  5455. +/**
  5456. + * This interrupt indicates that a device is initiating the Session
  5457. + * Request Protocol to request the host to turn on bus power so a new
  5458. + * session can begin. The handler responds by turning on bus power. If
  5459. + * the DWC_otg controller is in low power mode, the handler brings the
  5460. + * controller out of low power mode before turning on bus power.
  5461. + *
  5462. + * @param _core_if Programming view of DWC_otg controller.
  5463. + */
  5464. +int32_t dwc_otg_handle_session_req_intr( dwc_otg_core_if_t *_core_if )
  5465. +{
  5466. +#ifndef DWC_HOST_ONLY // winder
  5467. + hprt0_data_t hprt0;
  5468. +#endif
  5469. + gintsts_data_t gintsts;
  5470. +
  5471. +#ifndef DWC_HOST_ONLY
  5472. + DWC_DEBUGPL(DBG_ANY, "++Session Request Interrupt++\n");
  5473. +
  5474. + if (dwc_otg_is_device_mode(_core_if) ) {
  5475. + DWC_PRINT("SRP: Device mode\n");
  5476. + } else {
  5477. + DWC_PRINT("SRP: Host mode\n");
  5478. +
  5479. + /* Turn on the port power bit. */
  5480. + hprt0.d32 = dwc_otg_read_hprt0( _core_if );
  5481. + hprt0.b.prtpwr = 1;
  5482. + dwc_write_reg32(_core_if->host_if->hprt0, hprt0.d32);
  5483. +
  5484. + /* Start the Connection timer. So a message can be displayed
  5485. + * if connect does not occur within 10 seconds. */
  5486. + hcd_session_start( _core_if );
  5487. + }
  5488. +#endif
  5489. +
  5490. + /* Clear interrupt */
  5491. + gintsts.d32 = 0;
  5492. + gintsts.b.sessreqintr = 1;
  5493. + dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
  5494. +
  5495. + return 1;
  5496. +}
  5497. +
  5498. +/**
  5499. + * This interrupt indicates that the DWC_otg controller has detected a
  5500. + * resume or remote wakeup sequence. If the DWC_otg controller is in
  5501. + * low power mode, the handler must brings the controller out of low
  5502. + * power mode. The controller automatically begins resume
  5503. + * signaling. The handler schedules a time to stop resume signaling.
  5504. + */
  5505. +int32_t dwc_otg_handle_wakeup_detected_intr( dwc_otg_core_if_t *_core_if )
  5506. +{
  5507. + gintsts_data_t gintsts;
  5508. +
  5509. + DWC_DEBUGPL(DBG_ANY, "++Resume and Remote Wakeup Detected Interrupt++\n");
  5510. +
  5511. + if (dwc_otg_is_device_mode(_core_if) ) {
  5512. + dctl_data_t dctl = {.d32=0};
  5513. + DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n",
  5514. + dwc_read_reg32( &_core_if->dev_if->dev_global_regs->dsts));
  5515. +#ifdef PARTIAL_POWER_DOWN
  5516. + if (_core_if->hwcfg4.b.power_optimiz) {
  5517. + pcgcctl_data_t power = {.d32=0};
  5518. +
  5519. + power.d32 = dwc_read_reg32( _core_if->pcgcctl );
  5520. + DWC_DEBUGPL(DBG_CIL, "PCGCCTL=%0x\n", power.d32);
  5521. +
  5522. + power.b.stoppclk = 0;
  5523. + dwc_write_reg32( _core_if->pcgcctl, power.d32);
  5524. +
  5525. + power.b.pwrclmp = 0;
  5526. + dwc_write_reg32( _core_if->pcgcctl, power.d32);
  5527. +
  5528. + power.b.rstpdwnmodule = 0;
  5529. + dwc_write_reg32( _core_if->pcgcctl, power.d32);
  5530. + }
  5531. +#endif
  5532. + /* Clear the Remote Wakeup Signalling */
  5533. + dctl.b.rmtwkupsig = 1;
  5534. + dwc_modify_reg32( &_core_if->dev_if->dev_global_regs->dctl,
  5535. + dctl.d32, 0 );
  5536. +
  5537. + if (_core_if->pcd_cb && _core_if->pcd_cb->resume_wakeup) {
  5538. + _core_if->pcd_cb->resume_wakeup( _core_if->pcd_cb->p );
  5539. + }
  5540. +
  5541. + } else {
  5542. + /*
  5543. + * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
  5544. + * so that OPT tests pass with all PHYs).
  5545. + */
  5546. + hprt0_data_t hprt0 = {.d32=0};
  5547. + pcgcctl_data_t pcgcctl = {.d32=0};
  5548. + /* Restart the Phy Clock */
  5549. + pcgcctl.b.stoppclk = 1;
  5550. + dwc_modify_reg32(_core_if->pcgcctl, pcgcctl.d32, 0);
  5551. + UDELAY(10);
  5552. +
  5553. + /* Now wait for 70 ms. */
  5554. + hprt0.d32 = dwc_otg_read_hprt0( _core_if );
  5555. + DWC_DEBUGPL(DBG_ANY,"Resume: HPRT0=%0x\n", hprt0.d32);
  5556. + MDELAY(70);
  5557. + hprt0.b.prtres = 0; /* Resume */
  5558. + dwc_write_reg32(_core_if->host_if->hprt0, hprt0.d32);
  5559. + DWC_DEBUGPL(DBG_ANY,"Clear Resume: HPRT0=%0x\n", dwc_read_reg32(_core_if->host_if->hprt0));
  5560. + }
  5561. +
  5562. + /* Clear interrupt */
  5563. + gintsts.d32 = 0;
  5564. + gintsts.b.wkupintr = 1;
  5565. + dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
  5566. +
  5567. + return 1;
  5568. +}
  5569. +
  5570. +/**
  5571. + * This interrupt indicates that a device has been disconnected from
  5572. + * the root port.
  5573. + */
  5574. +int32_t dwc_otg_handle_disconnect_intr( dwc_otg_core_if_t *_core_if)
  5575. +{
  5576. + gintsts_data_t gintsts;
  5577. +
  5578. + DWC_DEBUGPL(DBG_ANY, "++Disconnect Detected Interrupt++ (%s) %s\n",
  5579. + (dwc_otg_is_host_mode(_core_if)?"Host":"Device"),
  5580. + op_state_str(_core_if));
  5581. +
  5582. +/** @todo Consolidate this if statement. */
  5583. +#ifndef DWC_HOST_ONLY
  5584. + if (_core_if->op_state == B_HOST) {
  5585. + /* If in device mode Disconnect and stop the HCD, then
  5586. + * start the PCD. */
  5587. + hcd_disconnect( _core_if );
  5588. + pcd_start( _core_if );
  5589. + _core_if->op_state = B_PERIPHERAL;
  5590. + } else if (dwc_otg_is_device_mode(_core_if)) {
  5591. + gotgctl_data_t gotgctl = { .d32 = 0 };
  5592. + gotgctl.d32 = dwc_read_reg32(&_core_if->core_global_regs->gotgctl);
  5593. + if (gotgctl.b.hstsethnpen==1) {
  5594. + /* Do nothing, if HNP in process the OTG
  5595. + * interrupt "Host Negotiation Detected"
  5596. + * interrupt will do the mode switch.
  5597. + */
  5598. + } else if (gotgctl.b.devhnpen == 0) {
  5599. + /* If in device mode Disconnect and stop the HCD, then
  5600. + * start the PCD. */
  5601. + hcd_disconnect( _core_if );
  5602. + pcd_start( _core_if );
  5603. + _core_if->op_state = B_PERIPHERAL;
  5604. + } else {
  5605. + DWC_DEBUGPL(DBG_ANY,"!a_peripheral && !devhnpen\n");
  5606. + }
  5607. + } else {
  5608. + if (_core_if->op_state == A_HOST) {
  5609. + /* A-Cable still connected but device disconnected. */
  5610. + hcd_disconnect( _core_if );
  5611. + }
  5612. + }
  5613. +#endif
  5614. +/* Without OTG, we should use the disconnect function!? winder added.*/
  5615. +#if 1 // NO OTG, so host only!!
  5616. + hcd_disconnect( _core_if );
  5617. +#endif
  5618. +
  5619. + gintsts.d32 = 0;
  5620. + gintsts.b.disconnect = 1;
  5621. + dwc_write_reg32 (&_core_if->core_global_regs->gintsts, gintsts.d32);
  5622. + return 1;
  5623. +}
  5624. +/**
  5625. + * This interrupt indicates that SUSPEND state has been detected on
  5626. + * the USB.
  5627. + *
  5628. + * For HNP the USB Suspend interrupt signals the change from
  5629. + * "a_peripheral" to "a_host".
  5630. + *
  5631. + * When power management is enabled the core will be put in low power
  5632. + * mode.
  5633. + */
  5634. +int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t *_core_if )
  5635. +{
  5636. + dsts_data_t dsts;
  5637. + gintsts_data_t gintsts;
  5638. +
  5639. + //805141:<IFTW-fchang>.removed DWC_DEBUGPL(DBG_ANY,"USB SUSPEND\n");
  5640. +
  5641. + if (dwc_otg_is_device_mode( _core_if ) ) {
  5642. + /* Check the Device status register to determine if the Suspend
  5643. + * state is active. */
  5644. + dsts.d32 = dwc_read_reg32( &_core_if->dev_if->dev_global_regs->dsts);
  5645. + DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", dsts.d32);
  5646. + DWC_DEBUGPL(DBG_PCD, "DSTS.Suspend Status=%d "
  5647. + "HWCFG4.power Optimize=%d\n",
  5648. + dsts.b.suspsts, _core_if->hwcfg4.b.power_optimiz);
  5649. +
  5650. +
  5651. +#ifdef PARTIAL_POWER_DOWN
  5652. +/** @todo Add a module parameter for power management. */
  5653. +
  5654. + if (dsts.b.suspsts && _core_if->hwcfg4.b.power_optimiz) {
  5655. + pcgcctl_data_t power = {.d32=0};
  5656. + DWC_DEBUGPL(DBG_CIL, "suspend\n");
  5657. +
  5658. + power.b.pwrclmp = 1;
  5659. + dwc_write_reg32( _core_if->pcgcctl, power.d32);
  5660. +
  5661. + power.b.rstpdwnmodule = 1;
  5662. + dwc_modify_reg32( _core_if->pcgcctl, 0, power.d32);
  5663. +
  5664. + power.b.stoppclk = 1;
  5665. + dwc_modify_reg32( _core_if->pcgcctl, 0, power.d32);
  5666. +
  5667. + } else {
  5668. + DWC_DEBUGPL(DBG_ANY,"disconnect?\n");
  5669. + }
  5670. +#endif
  5671. + /* PCD callback for suspend. */
  5672. + pcd_suspend(_core_if);
  5673. + } else {
  5674. + if (_core_if->op_state == A_PERIPHERAL) {
  5675. + DWC_DEBUGPL(DBG_ANY,"a_peripheral->a_host\n");
  5676. + /* Clear the a_peripheral flag, back to a_host. */
  5677. + pcd_stop( _core_if );
  5678. + hcd_start( _core_if );
  5679. + _core_if->op_state = A_HOST;
  5680. + }
  5681. + }
  5682. +
  5683. + /* Clear interrupt */
  5684. + gintsts.d32 = 0;
  5685. + gintsts.b.usbsuspend = 1;
  5686. + dwc_write_reg32( &_core_if->core_global_regs->gintsts, gintsts.d32);
  5687. +
  5688. + return 1;
  5689. +}
  5690. +
  5691. +
  5692. +/**
  5693. + * This function returns the Core Interrupt register.
  5694. + */
  5695. +static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t *_core_if)
  5696. +{
  5697. + gintsts_data_t gintsts;
  5698. + gintmsk_data_t gintmsk;
  5699. + gintmsk_data_t gintmsk_common = {.d32=0};
  5700. + gintmsk_common.b.wkupintr = 1;
  5701. + gintmsk_common.b.sessreqintr = 1;
  5702. + gintmsk_common.b.conidstschng = 1;
  5703. + gintmsk_common.b.otgintr = 1;
  5704. + gintmsk_common.b.modemismatch = 1;
  5705. + gintmsk_common.b.disconnect = 1;
  5706. + gintmsk_common.b.usbsuspend = 1;
  5707. + /** @todo: The port interrupt occurs while in device
  5708. + * mode. Added code to CIL to clear the interrupt for now!
  5709. + */
  5710. + gintmsk_common.b.portintr = 1;
  5711. +
  5712. + gintsts.d32 = dwc_read_reg32(&_core_if->core_global_regs->gintsts);
  5713. + gintmsk.d32 = dwc_read_reg32(&_core_if->core_global_regs->gintmsk);
  5714. +#ifdef DEBUG
  5715. + /* if any common interrupts set */
  5716. + if (gintsts.d32 & gintmsk_common.d32) {
  5717. + DWC_DEBUGPL(DBG_ANY, "gintsts=%08x gintmsk=%08x\n",
  5718. + gintsts.d32, gintmsk.d32);
  5719. + }
  5720. +#endif
  5721. +
  5722. + return ((gintsts.d32 & gintmsk.d32 ) & gintmsk_common.d32);
  5723. +
  5724. +}
  5725. +
  5726. +/**
  5727. + * Common interrupt handler.
  5728. + *
  5729. + * The common interrupts are those that occur in both Host and Device mode.
  5730. + * This handler handles the following interrupts:
  5731. + * - Mode Mismatch Interrupt
  5732. + * - Disconnect Interrupt
  5733. + * - OTG Interrupt
  5734. + * - Connector ID Status Change Interrupt
  5735. + * - Session Request Interrupt.
  5736. + * - Resume / Remote Wakeup Detected Interrupt.
  5737. + *
  5738. + */
  5739. +extern int32_t dwc_otg_handle_common_intr( dwc_otg_core_if_t *_core_if )
  5740. +{
  5741. + int retval = 0;
  5742. + gintsts_data_t gintsts;
  5743. +
  5744. + gintsts.d32 = dwc_otg_read_common_intr(_core_if);
  5745. +
  5746. + if (gintsts.b.modemismatch) {
  5747. + retval |= dwc_otg_handle_mode_mismatch_intr( _core_if );
  5748. + }
  5749. + if (gintsts.b.otgintr) {
  5750. + retval |= dwc_otg_handle_otg_intr( _core_if );
  5751. + }
  5752. + if (gintsts.b.conidstschng) {
  5753. + retval |= dwc_otg_handle_conn_id_status_change_intr( _core_if );
  5754. + }
  5755. + if (gintsts.b.disconnect) {
  5756. + retval |= dwc_otg_handle_disconnect_intr( _core_if );
  5757. + }
  5758. + if (gintsts.b.sessreqintr) {
  5759. + retval |= dwc_otg_handle_session_req_intr( _core_if );
  5760. + }
  5761. + if (gintsts.b.wkupintr) {
  5762. + retval |= dwc_otg_handle_wakeup_detected_intr( _core_if );
  5763. + }
  5764. + if (gintsts.b.usbsuspend) {
  5765. + retval |= dwc_otg_handle_usb_suspend_intr( _core_if );
  5766. + }
  5767. + if (gintsts.b.portintr && dwc_otg_is_device_mode(_core_if)) {
  5768. + /* The port interrupt occurs while in device mode with HPRT0
  5769. + * Port Enable/Disable.
  5770. + */
  5771. + gintsts.d32 = 0;
  5772. + gintsts.b.portintr = 1;
  5773. + dwc_write_reg32(&_core_if->core_global_regs->gintsts,
  5774. + gintsts.d32);
  5775. + retval |= 1;
  5776. +
  5777. + }
  5778. + return retval;
  5779. +}
  5780. diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c
  5781. new file mode 100644
  5782. index 0000000..1b0daab
  5783. --- /dev/null
  5784. +++ b/drivers/usb/dwc_otg/dwc_otg_driver.c
  5785. @@ -0,0 +1,1274 @@
  5786. +/* ==========================================================================
  5787. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_driver.c $
  5788. + * $Revision: 1.1.1.1 $
  5789. + * $Date: 2009-04-17 06:15:34 $
  5790. + * $Change: 631780 $
  5791. + *
  5792. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  5793. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  5794. + * otherwise expressly agreed to in writing between Synopsys and you.
  5795. + *
  5796. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  5797. + * any End User Software License Agreement or Agreement for Licensed Product
  5798. + * with Synopsys or any supplement thereto. You are permitted to use and
  5799. + * redistribute this Software in source and binary forms, with or without
  5800. + * modification, provided that redistributions of source code must retain this
  5801. + * notice. You may not view, use, disclose, copy or distribute this file or
  5802. + * any information contained herein except pursuant to this license grant from
  5803. + * Synopsys. If you do not agree with this notice, including the disclaimer
  5804. + * below, then you are not authorized to use the Software.
  5805. + *
  5806. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  5807. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  5808. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  5809. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  5810. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  5811. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  5812. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  5813. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  5814. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  5815. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  5816. + * DAMAGE.
  5817. + * ========================================================================== */
  5818. +
  5819. +/** @file
  5820. + * The dwc_otg_driver module provides the initialization and cleanup entry
  5821. + * points for the DWC_otg driver. This module will be dynamically installed
  5822. + * after Linux is booted using the insmod command. When the module is
  5823. + * installed, the dwc_otg_init function is called. When the module is
  5824. + * removed (using rmmod), the dwc_otg_cleanup function is called.
  5825. + *
  5826. + * This module also defines a data structure for the dwc_otg_driver, which is
  5827. + * used in conjunction with the standard ARM lm_device structure. These
  5828. + * structures allow the OTG driver to comply with the standard Linux driver
  5829. + * model in which devices and drivers are registered with a bus driver. This
  5830. + * has the benefit that Linux can expose attributes of the driver and device
  5831. + * in its special sysfs file system. Users can then read or write files in
  5832. + * this file system to perform diagnostics on the driver components or the
  5833. + * device.
  5834. + */
  5835. +
  5836. +#include <linux/kernel.h>
  5837. +#include <linux/module.h>
  5838. +#include <linux/moduleparam.h>
  5839. +#include <linux/init.h>
  5840. +#include <linux/gpio.h>
  5841. +
  5842. +#include <linux/device.h>
  5843. +#include <linux/platform_device.h>
  5844. +
  5845. +#include <linux/errno.h>
  5846. +#include <linux/types.h>
  5847. +#include <linux/stat.h> /* permission constants */
  5848. +#include <linux/irq.h>
  5849. +#include <asm/io.h>
  5850. +
  5851. +#include "dwc_otg_plat.h"
  5852. +#include "dwc_otg_attr.h"
  5853. +#include "dwc_otg_driver.h"
  5854. +#include "dwc_otg_cil.h"
  5855. +#include "dwc_otg_cil_ifx.h"
  5856. +
  5857. +// #include "dwc_otg_pcd.h" // device
  5858. +#include "dwc_otg_hcd.h" // host
  5859. +
  5860. +#include "dwc_otg_ifx.h" // for Infineon platform specific.
  5861. +
  5862. +#define DWC_DRIVER_VERSION "2.60a 22-NOV-2006"
  5863. +#define DWC_DRIVER_DESC "HS OTG USB Controller driver"
  5864. +
  5865. +const char dwc_driver_name[] = "dwc_otg";
  5866. +
  5867. +static unsigned long dwc_iomem_base = IFX_USB_IOMEM_BASE;
  5868. +int dwc_irq = LTQ_USB_INT;
  5869. +//int dwc_irq = 54;
  5870. +//int dwc_irq = IFXMIPS_USB_OC_INT;
  5871. +
  5872. +extern int ifx_usb_hc_init(unsigned long base_addr, int irq);
  5873. +extern void ifx_usb_hc_remove(void);
  5874. +
  5875. +/*-------------------------------------------------------------------------*/
  5876. +/* Encapsulate the module parameter settings */
  5877. +
  5878. +static dwc_otg_core_params_t dwc_otg_module_params = {
  5879. + .opt = -1,
  5880. + .otg_cap = -1,
  5881. + .dma_enable = -1,
  5882. + .dma_burst_size = -1,
  5883. + .speed = -1,
  5884. + .host_support_fs_ls_low_power = -1,
  5885. + .host_ls_low_power_phy_clk = -1,
  5886. + .enable_dynamic_fifo = -1,
  5887. + .data_fifo_size = -1,
  5888. + .dev_rx_fifo_size = -1,
  5889. + .dev_nperio_tx_fifo_size = -1,
  5890. + .dev_perio_tx_fifo_size = /* dev_perio_tx_fifo_size_1 */ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 15 */
  5891. + .host_rx_fifo_size = -1,
  5892. + .host_nperio_tx_fifo_size = -1,
  5893. + .host_perio_tx_fifo_size = -1,
  5894. + .max_transfer_size = -1,
  5895. + .max_packet_count = -1,
  5896. + .host_channels = -1,
  5897. + .dev_endpoints = -1,
  5898. + .phy_type = -1,
  5899. + .phy_utmi_width = -1,
  5900. + .phy_ulpi_ddr = -1,
  5901. + .phy_ulpi_ext_vbus = -1,
  5902. + .i2c_enable = -1,
  5903. + .ulpi_fs_ls = -1,
  5904. + .ts_dline = -1,
  5905. + .en_multiple_tx_fifo = -1,
  5906. + .dev_tx_fifo_size = { /* dev_tx_fifo_size */
  5907. + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
  5908. + }, /* 15 */
  5909. + .thr_ctl = -1,
  5910. + .tx_thr_length = -1,
  5911. + .rx_thr_length = -1,
  5912. +};
  5913. +
  5914. +/**
  5915. + * This function shows the Driver Version.
  5916. + */
  5917. +static ssize_t version_show(struct device_driver *dev, char *buf)
  5918. +{
  5919. + return snprintf(buf, sizeof(DWC_DRIVER_VERSION)+2,"%s\n",
  5920. + DWC_DRIVER_VERSION);
  5921. +}
  5922. +static DRIVER_ATTR(version, S_IRUGO, version_show, NULL);
  5923. +
  5924. +/**
  5925. + * Global Debug Level Mask.
  5926. + */
  5927. +uint32_t g_dbg_lvl = 0xff; /* OFF */
  5928. +
  5929. +/**
  5930. + * This function shows the driver Debug Level.
  5931. + */
  5932. +static ssize_t dbg_level_show(struct device_driver *_drv, char *_buf)
  5933. +{
  5934. + return sprintf(_buf, "0x%0x\n", g_dbg_lvl);
  5935. +}
  5936. +/**
  5937. + * This function stores the driver Debug Level.
  5938. + */
  5939. +static ssize_t dbg_level_store(struct device_driver *_drv, const char *_buf,
  5940. + size_t _count)
  5941. +{
  5942. + g_dbg_lvl = simple_strtoul(_buf, NULL, 16);
  5943. + return _count;
  5944. +}
  5945. +static DRIVER_ATTR(debuglevel, S_IRUGO|S_IWUSR, dbg_level_show, dbg_level_store);
  5946. +
  5947. +/**
  5948. + * This function is called during module intialization to verify that
  5949. + * the module parameters are in a valid state.
  5950. + */
  5951. +static int check_parameters(dwc_otg_core_if_t *core_if)
  5952. +{
  5953. + int i;
  5954. + int retval = 0;
  5955. +
  5956. +/* Checks if the parameter is outside of its valid range of values */
  5957. +#define DWC_OTG_PARAM_TEST(_param_,_low_,_high_) \
  5958. + ((dwc_otg_module_params._param_ < (_low_)) || \
  5959. + (dwc_otg_module_params._param_ > (_high_)))
  5960. +
  5961. +/* If the parameter has been set by the user, check that the parameter value is
  5962. + * within the value range of values. If not, report a module error. */
  5963. +#define DWC_OTG_PARAM_ERR(_param_,_low_,_high_,_string_) \
  5964. + do { \
  5965. + if (dwc_otg_module_params._param_ != -1) { \
  5966. + if (DWC_OTG_PARAM_TEST(_param_,(_low_),(_high_))) { \
  5967. + DWC_ERROR("`%d' invalid for parameter `%s'\n", \
  5968. + dwc_otg_module_params._param_, _string_); \
  5969. + dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
  5970. + retval ++; \
  5971. + } \
  5972. + } \
  5973. + } while (0)
  5974. +
  5975. + DWC_OTG_PARAM_ERR(opt,0,1,"opt");
  5976. + DWC_OTG_PARAM_ERR(otg_cap,0,2,"otg_cap");
  5977. + DWC_OTG_PARAM_ERR(dma_enable,0,1,"dma_enable");
  5978. + DWC_OTG_PARAM_ERR(speed,0,1,"speed");
  5979. + DWC_OTG_PARAM_ERR(host_support_fs_ls_low_power,0,1,"host_support_fs_ls_low_power");
  5980. + DWC_OTG_PARAM_ERR(host_ls_low_power_phy_clk,0,1,"host_ls_low_power_phy_clk");
  5981. + DWC_OTG_PARAM_ERR(enable_dynamic_fifo,0,1,"enable_dynamic_fifo");
  5982. + DWC_OTG_PARAM_ERR(data_fifo_size,32,32768,"data_fifo_size");
  5983. + DWC_OTG_PARAM_ERR(dev_rx_fifo_size,16,32768,"dev_rx_fifo_size");
  5984. + DWC_OTG_PARAM_ERR(dev_nperio_tx_fifo_size,16,32768,"dev_nperio_tx_fifo_size");
  5985. + DWC_OTG_PARAM_ERR(host_rx_fifo_size,16,32768,"host_rx_fifo_size");
  5986. + DWC_OTG_PARAM_ERR(host_nperio_tx_fifo_size,16,32768,"host_nperio_tx_fifo_size");
  5987. + DWC_OTG_PARAM_ERR(host_perio_tx_fifo_size,16,32768,"host_perio_tx_fifo_size");
  5988. + DWC_OTG_PARAM_ERR(max_transfer_size,2047,524288,"max_transfer_size");
  5989. + DWC_OTG_PARAM_ERR(max_packet_count,15,511,"max_packet_count");
  5990. + DWC_OTG_PARAM_ERR(host_channels,1,16,"host_channels");
  5991. + DWC_OTG_PARAM_ERR(dev_endpoints,1,15,"dev_endpoints");
  5992. + DWC_OTG_PARAM_ERR(phy_type,0,2,"phy_type");
  5993. + DWC_OTG_PARAM_ERR(phy_ulpi_ddr,0,1,"phy_ulpi_ddr");
  5994. + DWC_OTG_PARAM_ERR(phy_ulpi_ext_vbus,0,1,"phy_ulpi_ext_vbus");
  5995. + DWC_OTG_PARAM_ERR(i2c_enable,0,1,"i2c_enable");
  5996. + DWC_OTG_PARAM_ERR(ulpi_fs_ls,0,1,"ulpi_fs_ls");
  5997. + DWC_OTG_PARAM_ERR(ts_dline,0,1,"ts_dline");
  5998. +
  5999. + if (dwc_otg_module_params.dma_burst_size != -1) {
  6000. + if (DWC_OTG_PARAM_TEST(dma_burst_size,1,1) &&
  6001. + DWC_OTG_PARAM_TEST(dma_burst_size,4,4) &&
  6002. + DWC_OTG_PARAM_TEST(dma_burst_size,8,8) &&
  6003. + DWC_OTG_PARAM_TEST(dma_burst_size,16,16) &&
  6004. + DWC_OTG_PARAM_TEST(dma_burst_size,32,32) &&
  6005. + DWC_OTG_PARAM_TEST(dma_burst_size,64,64) &&
  6006. + DWC_OTG_PARAM_TEST(dma_burst_size,128,128) &&
  6007. + DWC_OTG_PARAM_TEST(dma_burst_size,256,256))
  6008. + {
  6009. + DWC_ERROR("`%d' invalid for parameter `dma_burst_size'\n",
  6010. + dwc_otg_module_params.dma_burst_size);
  6011. + dwc_otg_module_params.dma_burst_size = 32;
  6012. + retval ++;
  6013. + }
  6014. + }
  6015. +
  6016. + if (dwc_otg_module_params.phy_utmi_width != -1) {
  6017. + if (DWC_OTG_PARAM_TEST(phy_utmi_width,8,8) &&
  6018. + DWC_OTG_PARAM_TEST(phy_utmi_width,16,16))
  6019. + {
  6020. + DWC_ERROR("`%d' invalid for parameter `phy_utmi_width'\n",
  6021. + dwc_otg_module_params.phy_utmi_width);
  6022. + //dwc_otg_module_params.phy_utmi_width = 16;
  6023. + dwc_otg_module_params.phy_utmi_width = 8;
  6024. + retval ++;
  6025. + }
  6026. + }
  6027. +
  6028. + for (i=0; i<15; i++) {
  6029. + /** @todo should be like above */
  6030. + //DWC_OTG_PARAM_ERR(dev_perio_tx_fifo_size[i],4,768,"dev_perio_tx_fifo_size");
  6031. + if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] != -1) {
  6032. + if (DWC_OTG_PARAM_TEST(dev_perio_tx_fifo_size[i],4,768)) {
  6033. + DWC_ERROR("`%d' invalid for parameter `%s_%d'\n",
  6034. + dwc_otg_module_params.dev_perio_tx_fifo_size[i], "dev_perio_tx_fifo_size", i);
  6035. + dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default;
  6036. + retval ++;
  6037. + }
  6038. + }
  6039. + }
  6040. +
  6041. + DWC_OTG_PARAM_ERR(en_multiple_tx_fifo, 0, 1, "en_multiple_tx_fifo");
  6042. + for (i = 0; i < 15; i++) {
  6043. + /** @todo should be like above */
  6044. + //DWC_OTG_PARAM_ERR(dev_tx_fifo_size[i],4,768,"dev_tx_fifo_size");
  6045. + if (dwc_otg_module_params.dev_tx_fifo_size[i] != -1) {
  6046. + if (DWC_OTG_PARAM_TEST(dev_tx_fifo_size[i], 4, 768)) {
  6047. + DWC_ERROR("`%d' invalid for parameter `%s_%d'\n",
  6048. + dwc_otg_module_params.dev_tx_fifo_size[i],
  6049. + "dev_tx_fifo_size", i);
  6050. + dwc_otg_module_params.dev_tx_fifo_size[i] =
  6051. + dwc_param_dev_tx_fifo_size_default;
  6052. + retval++;
  6053. + }
  6054. + }
  6055. + }
  6056. + DWC_OTG_PARAM_ERR(thr_ctl, 0, 7, "thr_ctl");
  6057. + DWC_OTG_PARAM_ERR(tx_thr_length, 8, 128, "tx_thr_length");
  6058. + DWC_OTG_PARAM_ERR(rx_thr_length, 8, 128, "rx_thr_length");
  6059. +
  6060. + /* At this point, all module parameters that have been set by the user
  6061. + * are valid, and those that have not are left unset. Now set their
  6062. + * default values and/or check the parameters against the hardware
  6063. + * configurations of the OTG core. */
  6064. +
  6065. +
  6066. +
  6067. +/* This sets the parameter to the default value if it has not been set by the
  6068. + * user */
  6069. +#define DWC_OTG_PARAM_SET_DEFAULT(_param_) \
  6070. + ({ \
  6071. + int changed = 1; \
  6072. + if (dwc_otg_module_params._param_ == -1) { \
  6073. + changed = 0; \
  6074. + dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \
  6075. + } \
  6076. + changed; \
  6077. + })
  6078. +
  6079. +/* This checks the macro agains the hardware configuration to see if it is
  6080. + * valid. It is possible that the default value could be invalid. In this
  6081. + * case, it will report a module error if the user touched the parameter.
  6082. + * Otherwise it will adjust the value without any error. */
  6083. +#define DWC_OTG_PARAM_CHECK_VALID(_param_,_str_,_is_valid_,_set_valid_) \
  6084. + ({ \
  6085. + int changed = DWC_OTG_PARAM_SET_DEFAULT(_param_); \
  6086. + int error = 0; \
  6087. + if (!(_is_valid_)) { \
  6088. + if (changed) { \
  6089. + DWC_ERROR("`%d' invalid for parameter `%s'. Check HW configuration.\n", dwc_otg_module_params._param_,_str_); \
  6090. + error = 1; \
  6091. + } \
  6092. + dwc_otg_module_params._param_ = (_set_valid_); \
  6093. + } \
  6094. + error; \
  6095. + })
  6096. +
  6097. + /* OTG Cap */
  6098. + retval += DWC_OTG_PARAM_CHECK_VALID(otg_cap,"otg_cap",
  6099. + ({
  6100. + int valid;
  6101. + valid = 1;
  6102. + switch (dwc_otg_module_params.otg_cap) {
  6103. + case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
  6104. + if (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) valid = 0;
  6105. + break;
  6106. + case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
  6107. + if ((core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) &&
  6108. + (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) &&
  6109. + (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) &&
  6110. + (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST))
  6111. + {
  6112. + valid = 0;
  6113. + }
  6114. + break;
  6115. + case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
  6116. + /* always valid */
  6117. + break;
  6118. + }
  6119. + valid;
  6120. + }),
  6121. + (((core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) ||
  6122. + (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) ||
  6123. + (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) ||
  6124. + (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
  6125. + DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
  6126. + DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE));
  6127. +
  6128. + retval += DWC_OTG_PARAM_CHECK_VALID(dma_enable,"dma_enable",
  6129. + ((dwc_otg_module_params.dma_enable == 1) && (core_if->hwcfg2.b.architecture == 0)) ? 0 : 1,
  6130. + 0);
  6131. +
  6132. + retval += DWC_OTG_PARAM_CHECK_VALID(opt,"opt",
  6133. + 1,
  6134. + 0);
  6135. +
  6136. + DWC_OTG_PARAM_SET_DEFAULT(dma_burst_size);
  6137. +
  6138. + retval += DWC_OTG_PARAM_CHECK_VALID(host_support_fs_ls_low_power,
  6139. + "host_support_fs_ls_low_power",
  6140. + 1, 0);
  6141. +
  6142. + retval += DWC_OTG_PARAM_CHECK_VALID(enable_dynamic_fifo,
  6143. + "enable_dynamic_fifo",
  6144. + ((dwc_otg_module_params.enable_dynamic_fifo == 0) ||
  6145. + (core_if->hwcfg2.b.dynamic_fifo == 1)), 0);
  6146. +
  6147. +
  6148. + retval += DWC_OTG_PARAM_CHECK_VALID(data_fifo_size,
  6149. + "data_fifo_size",
  6150. + (dwc_otg_module_params.data_fifo_size <= core_if->hwcfg3.b.dfifo_depth),
  6151. + core_if->hwcfg3.b.dfifo_depth);
  6152. +
  6153. + retval += DWC_OTG_PARAM_CHECK_VALID(dev_rx_fifo_size,
  6154. + "dev_rx_fifo_size",
  6155. + (dwc_otg_module_params.dev_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)),
  6156. + dwc_read_reg32(&core_if->core_global_regs->grxfsiz));
  6157. +
  6158. + retval += DWC_OTG_PARAM_CHECK_VALID(dev_nperio_tx_fifo_size,
  6159. + "dev_nperio_tx_fifo_size",
  6160. + (dwc_otg_module_params.dev_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)),
  6161. + (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16));
  6162. +
  6163. + retval += DWC_OTG_PARAM_CHECK_VALID(host_rx_fifo_size,
  6164. + "host_rx_fifo_size",
  6165. + (dwc_otg_module_params.host_rx_fifo_size <= dwc_read_reg32(&core_if->core_global_regs->grxfsiz)),
  6166. + dwc_read_reg32(&core_if->core_global_regs->grxfsiz));
  6167. +
  6168. +
  6169. + retval += DWC_OTG_PARAM_CHECK_VALID(host_nperio_tx_fifo_size,
  6170. + "host_nperio_tx_fifo_size",
  6171. + (dwc_otg_module_params.host_nperio_tx_fifo_size <= (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)),
  6172. + (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16));
  6173. +
  6174. + retval += DWC_OTG_PARAM_CHECK_VALID(host_perio_tx_fifo_size,
  6175. + "host_perio_tx_fifo_size",
  6176. + (dwc_otg_module_params.host_perio_tx_fifo_size <= ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))),
  6177. + ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16)));
  6178. +
  6179. + retval += DWC_OTG_PARAM_CHECK_VALID(max_transfer_size,
  6180. + "max_transfer_size",
  6181. + (dwc_otg_module_params.max_transfer_size < (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))),
  6182. + ((1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1));
  6183. +
  6184. + retval += DWC_OTG_PARAM_CHECK_VALID(max_packet_count,
  6185. + "max_packet_count",
  6186. + (dwc_otg_module_params.max_packet_count < (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))),
  6187. + ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1));
  6188. +
  6189. + retval += DWC_OTG_PARAM_CHECK_VALID(host_channels,
  6190. + "host_channels",
  6191. + (dwc_otg_module_params.host_channels <= (core_if->hwcfg2.b.num_host_chan + 1)),
  6192. + (core_if->hwcfg2.b.num_host_chan + 1));
  6193. +
  6194. + retval += DWC_OTG_PARAM_CHECK_VALID(dev_endpoints,
  6195. + "dev_endpoints",
  6196. + (dwc_otg_module_params.dev_endpoints <= (core_if->hwcfg2.b.num_dev_ep)),
  6197. + core_if->hwcfg2.b.num_dev_ep);
  6198. +
  6199. +/*
  6200. + * Define the following to disable the FS PHY Hardware checking. This is for
  6201. + * internal testing only.
  6202. + *
  6203. + * #define NO_FS_PHY_HW_CHECKS
  6204. + */
  6205. +
  6206. +#ifdef NO_FS_PHY_HW_CHECKS
  6207. + retval += DWC_OTG_PARAM_CHECK_VALID(phy_type,
  6208. + "phy_type", 1, 0);
  6209. +#else
  6210. + retval += DWC_OTG_PARAM_CHECK_VALID(phy_type,
  6211. + "phy_type",
  6212. + ({
  6213. + int valid = 0;
  6214. + if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_UTMI) &&
  6215. + ((core_if->hwcfg2.b.hs_phy_type == 1) ||
  6216. + (core_if->hwcfg2.b.hs_phy_type == 3)))
  6217. + {
  6218. + valid = 1;
  6219. + }
  6220. + else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_ULPI) &&
  6221. + ((core_if->hwcfg2.b.hs_phy_type == 2) ||
  6222. + (core_if->hwcfg2.b.hs_phy_type == 3)))
  6223. + {
  6224. + valid = 1;
  6225. + }
  6226. + else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) &&
  6227. + (core_if->hwcfg2.b.fs_phy_type == 1))
  6228. + {
  6229. + valid = 1;
  6230. + }
  6231. + valid;
  6232. + }),
  6233. + ({
  6234. + int set = DWC_PHY_TYPE_PARAM_FS;
  6235. + if (core_if->hwcfg2.b.hs_phy_type) {
  6236. + if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
  6237. + (core_if->hwcfg2.b.hs_phy_type == 1)) {
  6238. + set = DWC_PHY_TYPE_PARAM_UTMI;
  6239. + }
  6240. + else {
  6241. + set = DWC_PHY_TYPE_PARAM_ULPI;
  6242. + }
  6243. + }
  6244. + set;
  6245. + }));
  6246. +#endif
  6247. +
  6248. + retval += DWC_OTG_PARAM_CHECK_VALID(speed,"speed",
  6249. + (dwc_otg_module_params.speed == 0) && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1,
  6250. + dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
  6251. +
  6252. + retval += DWC_OTG_PARAM_CHECK_VALID(host_ls_low_power_phy_clk,
  6253. + "host_ls_low_power_phy_clk",
  6254. + ((dwc_otg_module_params.host_ls_low_power_phy_clk == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ) && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1),
  6255. + ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ : DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ));
  6256. +
  6257. + DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ddr);
  6258. + DWC_OTG_PARAM_SET_DEFAULT(phy_ulpi_ext_vbus);
  6259. + DWC_OTG_PARAM_SET_DEFAULT(phy_utmi_width);
  6260. + DWC_OTG_PARAM_SET_DEFAULT(ulpi_fs_ls);
  6261. + DWC_OTG_PARAM_SET_DEFAULT(ts_dline);
  6262. +
  6263. +#ifdef NO_FS_PHY_HW_CHECKS
  6264. + retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable,
  6265. + "i2c_enable", 1, 0);
  6266. +#else
  6267. + retval += DWC_OTG_PARAM_CHECK_VALID(i2c_enable,
  6268. + "i2c_enable",
  6269. + (dwc_otg_module_params.i2c_enable == 1) && (core_if->hwcfg3.b.i2c == 0) ? 0 : 1,
  6270. + 0);
  6271. +#endif
  6272. +
  6273. + for (i=0; i<16; i++) {
  6274. +
  6275. + int changed = 1;
  6276. + int error = 0;
  6277. +
  6278. + if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] == -1) {
  6279. + changed = 0;
  6280. + dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_param_dev_perio_tx_fifo_size_default;
  6281. + }
  6282. + if (!(dwc_otg_module_params.dev_perio_tx_fifo_size[i] <= (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) {
  6283. + if (changed) {
  6284. + DWC_ERROR("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n", dwc_otg_module_params.dev_perio_tx_fifo_size[i],i);
  6285. + error = 1;
  6286. + }
  6287. + dwc_otg_module_params.dev_perio_tx_fifo_size[i] = dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]);
  6288. + }
  6289. + retval += error;
  6290. + }
  6291. +
  6292. + retval += DWC_OTG_PARAM_CHECK_VALID(en_multiple_tx_fifo,
  6293. + "en_multiple_tx_fifo",
  6294. + ((dwc_otg_module_params.en_multiple_tx_fifo == 1) &&
  6295. + (core_if->hwcfg4.b.ded_fifo_en == 0)) ? 0 : 1, 0);
  6296. +
  6297. + for (i = 0; i < 16; i++) {
  6298. + int changed = 1;
  6299. + int error = 0;
  6300. + if (dwc_otg_module_params.dev_tx_fifo_size[i] == -1) {
  6301. + changed = 0;
  6302. + dwc_otg_module_params.dev_tx_fifo_size[i] =
  6303. + dwc_param_dev_tx_fifo_size_default;
  6304. + }
  6305. + if (!(dwc_otg_module_params.dev_tx_fifo_size[i] <=
  6306. + (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i])))) {
  6307. + if (changed) {
  6308. + DWC_ERROR("%d' invalid for parameter `dev_perio_fifo_size_%d'."
  6309. + "Check HW configuration.\n",dwc_otg_module_params.dev_tx_fifo_size[i],i);
  6310. + error = 1;
  6311. + }
  6312. + dwc_otg_module_params.dev_tx_fifo_size[i] =
  6313. + dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[i]);
  6314. + }
  6315. + retval += error;
  6316. + }
  6317. + DWC_OTG_PARAM_SET_DEFAULT(thr_ctl);
  6318. + DWC_OTG_PARAM_SET_DEFAULT(tx_thr_length);
  6319. + DWC_OTG_PARAM_SET_DEFAULT(rx_thr_length);
  6320. + return retval;
  6321. +} // check_parameters
  6322. +
  6323. +
  6324. +/**
  6325. + * This function is the top level interrupt handler for the Common
  6326. + * (Device and host modes) interrupts.
  6327. + */
  6328. +static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev)
  6329. +{
  6330. + dwc_otg_device_t *otg_dev = _dev;
  6331. + int32_t retval = IRQ_NONE;
  6332. +
  6333. + retval = dwc_otg_handle_common_intr( otg_dev->core_if );
  6334. +
  6335. + mask_and_ack_ifx_irq (_irq);
  6336. +
  6337. + return IRQ_RETVAL(retval);
  6338. +}
  6339. +
  6340. +
  6341. +/**
  6342. + * This function is called when a DWC_OTG device is unregistered with the
  6343. + * dwc_otg_driver. This happens, for example, when the rmmod command is
  6344. + * executed. The device may or may not be electrically present. If it is
  6345. + * present, the driver stops device processing. Any resources used on behalf
  6346. + * of this device are freed.
  6347. + *
  6348. + * @return
  6349. + */
  6350. +static int
  6351. +dwc_otg_driver_remove(struct platform_device *_dev)
  6352. +{
  6353. + //dwc_otg_device_t *otg_dev = dev_get_drvdata(&_dev->dev);
  6354. + dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev);
  6355. +
  6356. + DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, _dev);
  6357. +
  6358. + if (otg_dev == NULL) {
  6359. + /* Memory allocation for the dwc_otg_device failed. */
  6360. + return 0;
  6361. + }
  6362. +
  6363. + /*
  6364. + * Free the IRQ
  6365. + */
  6366. + if (otg_dev->common_irq_installed) {
  6367. + free_irq( otg_dev->irq, otg_dev );
  6368. + }
  6369. +
  6370. +#ifndef DWC_DEVICE_ONLY
  6371. + if (otg_dev->hcd != NULL) {
  6372. + dwc_otg_hcd_remove(&_dev->dev);
  6373. + }
  6374. +#endif
  6375. + printk("after removehcd\n");
  6376. +
  6377. +// Note: Integrate HOST and DEVICE(Gadget) is not planned yet.
  6378. +#ifndef DWC_HOST_ONLY
  6379. + if (otg_dev->pcd != NULL) {
  6380. + dwc_otg_pcd_remove(otg_dev);
  6381. + }
  6382. +#endif
  6383. + if (otg_dev->core_if != NULL) {
  6384. + dwc_otg_cil_remove( otg_dev->core_if );
  6385. + }
  6386. + printk("after removecil\n");
  6387. +
  6388. + /*
  6389. + * Remove the device attributes
  6390. + */
  6391. + dwc_otg_attr_remove(&_dev->dev);
  6392. + printk("after removeattr\n");
  6393. +
  6394. + /*
  6395. + * Return the memory.
  6396. + */
  6397. + if (otg_dev->base != NULL) {
  6398. + iounmap(otg_dev->base);
  6399. + }
  6400. + if (otg_dev->phys_addr != 0) {
  6401. + release_mem_region(otg_dev->phys_addr, otg_dev->base_len);
  6402. + }
  6403. + kfree(otg_dev);
  6404. +
  6405. + /*
  6406. + * Clear the drvdata pointer.
  6407. + */
  6408. + //dev_set_drvdata(&_dev->dev, 0);
  6409. + platform_set_drvdata(_dev, 0);
  6410. + return 0;
  6411. +}
  6412. +
  6413. +/**
  6414. + * This function is called when an DWC_OTG device is bound to a
  6415. + * dwc_otg_driver. It creates the driver components required to
  6416. + * control the device (CIL, HCD, and PCD) and it initializes the
  6417. + * device. The driver components are stored in a dwc_otg_device
  6418. + * structure. A reference to the dwc_otg_device is saved in the
  6419. + * lm_device. This allows the driver to access the dwc_otg_device
  6420. + * structure on subsequent calls to driver methods for this device.
  6421. + *
  6422. + * @return
  6423. + */
  6424. +static int __devinit
  6425. +dwc_otg_driver_probe(struct platform_device *_dev)
  6426. +{
  6427. + int retval = 0;
  6428. + dwc_otg_device_t *dwc_otg_device;
  6429. + int pin = (int)_dev->dev.platform_data;
  6430. + int32_t snpsid;
  6431. + struct resource *res;
  6432. + gusbcfg_data_t usbcfg = {.d32 = 0};
  6433. +
  6434. + // GPIOs
  6435. + if(pin >= 0)
  6436. + {
  6437. + gpio_request(pin, "usb_power");
  6438. + gpio_direction_output(pin, 1);
  6439. + gpio_set_value(pin, 1);
  6440. + gpio_export(pin, 0);
  6441. + }
  6442. + dev_dbg(&_dev->dev, "dwc_otg_driver_probe (%p)\n", _dev);
  6443. +
  6444. + dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL);
  6445. + if (dwc_otg_device == 0) {
  6446. + dev_err(&_dev->dev, "kmalloc of dwc_otg_device failed\n");
  6447. + retval = -ENOMEM;
  6448. + goto fail;
  6449. + }
  6450. + memset(dwc_otg_device, 0, sizeof(*dwc_otg_device));
  6451. + dwc_otg_device->reg_offset = 0xFFFFFFFF;
  6452. +
  6453. + /*
  6454. + * Retrieve the memory and IRQ resources.
  6455. + */
  6456. + dwc_otg_device->irq = platform_get_irq(_dev, 0);
  6457. + if (dwc_otg_device->irq == 0) {
  6458. + dev_err(&_dev->dev, "no device irq\n");
  6459. + retval = -ENODEV;
  6460. + goto fail;
  6461. + }
  6462. + dev_dbg(&_dev->dev, "OTG - device irq: %d\n", dwc_otg_device->irq);
  6463. + res = platform_get_resource(_dev, IORESOURCE_MEM, 0);
  6464. + if (res == NULL) {
  6465. + dev_err(&_dev->dev, "no CSR address\n");
  6466. + retval = -ENODEV;
  6467. + goto fail;
  6468. + }
  6469. + dev_dbg(&_dev->dev, "OTG - ioresource_mem start0x%08x: end:0x%08x\n",
  6470. + (unsigned)res->start, (unsigned)res->end);
  6471. + dwc_otg_device->phys_addr = res->start;
  6472. + dwc_otg_device->base_len = res->end - res->start + 1;
  6473. + if (request_mem_region(dwc_otg_device->phys_addr, dwc_otg_device->base_len,
  6474. + dwc_driver_name) == NULL) {
  6475. + dev_err(&_dev->dev, "request_mem_region failed\n");
  6476. + retval = -EBUSY;
  6477. + goto fail;
  6478. + }
  6479. +
  6480. + /*
  6481. + * Map the DWC_otg Core memory into virtual address space.
  6482. + */
  6483. + dwc_otg_device->base = ioremap_nocache(dwc_otg_device->phys_addr, dwc_otg_device->base_len);
  6484. + if (dwc_otg_device->base == NULL) {
  6485. + dev_err(&_dev->dev, "ioremap() failed\n");
  6486. + retval = -ENOMEM;
  6487. + goto fail;
  6488. + }
  6489. + dev_dbg(&_dev->dev, "mapped base=0x%08x\n", (unsigned)dwc_otg_device->base);
  6490. +
  6491. + /*
  6492. + * Attempt to ensure this device is really a DWC_otg Controller.
  6493. + * Read and verify the SNPSID register contents. The value should be
  6494. + * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX".
  6495. + */
  6496. + snpsid = dwc_read_reg32((uint32_t *)((uint8_t *)dwc_otg_device->base + 0x40));
  6497. + if ((snpsid & 0xFFFFF000) != 0x4F542000) {
  6498. + dev_err(&_dev->dev, "Bad value for SNPSID: 0x%08x\n", snpsid);
  6499. + retval = -EINVAL;
  6500. + goto fail;
  6501. + }
  6502. +
  6503. + /*
  6504. + * Initialize driver data to point to the global DWC_otg
  6505. + * Device structure.
  6506. + */
  6507. + platform_set_drvdata(_dev, dwc_otg_device);
  6508. + dev_dbg(&_dev->dev, "dwc_otg_device=0x%p\n", dwc_otg_device);
  6509. + dwc_otg_device->core_if = dwc_otg_cil_init( dwc_otg_device->base, &dwc_otg_module_params);
  6510. + if (dwc_otg_device->core_if == 0) {
  6511. + dev_err(&_dev->dev, "CIL initialization failed!\n");
  6512. + retval = -ENOMEM;
  6513. + goto fail;
  6514. + }
  6515. +
  6516. + /*
  6517. + * Validate parameter values.
  6518. + */
  6519. + if (check_parameters(dwc_otg_device->core_if) != 0) {
  6520. + retval = -EINVAL;
  6521. + goto fail;
  6522. + }
  6523. +
  6524. + /* Added for PLB DMA phys virt mapping */
  6525. + //dwc_otg_device->core_if->phys_addr = dwc_otg_device->phys_addr;
  6526. + /*
  6527. + * Create Device Attributes in sysfs
  6528. + */
  6529. + dwc_otg_attr_create (&_dev->dev);
  6530. +
  6531. + /*
  6532. + * Disable the global interrupt until all the interrupt
  6533. + * handlers are installed.
  6534. + */
  6535. + dwc_otg_disable_global_interrupts( dwc_otg_device->core_if );
  6536. + /*
  6537. + * Install the interrupt handler for the common interrupts before
  6538. + * enabling common interrupts in core_init below.
  6539. + */
  6540. + DWC_DEBUGPL( DBG_CIL, "registering (common) handler for irq%d\n", dwc_otg_device->irq);
  6541. +
  6542. + retval = request_irq((unsigned int)dwc_otg_device->irq, dwc_otg_common_irq,
  6543. + //SA_INTERRUPT|SA_SHIRQ, "dwc_otg", (void *)dwc_otg_device );
  6544. + IRQF_SHARED, "dwc_otg", (void *)dwc_otg_device );
  6545. + //IRQF_DISABLED, "dwc_otg", (void *)dwc_otg_device );
  6546. + if (retval != 0) {
  6547. + DWC_ERROR("request of irq%d failed retval: %d\n", dwc_otg_device->irq, retval);
  6548. + retval = -EBUSY;
  6549. + goto fail;
  6550. + } else {
  6551. + dwc_otg_device->common_irq_installed = 1;
  6552. + }
  6553. +
  6554. + /*
  6555. + * Initialize the DWC_otg core.
  6556. + */
  6557. + dwc_otg_core_init( dwc_otg_device->core_if );
  6558. +
  6559. +
  6560. +#ifndef DWC_HOST_ONLY // otg device mode. (gadget.)
  6561. + /*
  6562. + * Initialize the PCD
  6563. + */
  6564. + retval = dwc_otg_pcd_init(dwc_otg_device);
  6565. + if (retval != 0) {
  6566. + DWC_ERROR("dwc_otg_pcd_init failed\n");
  6567. + dwc_otg_device->pcd = NULL;
  6568. + goto fail;
  6569. + }
  6570. +#endif // DWC_HOST_ONLY
  6571. +
  6572. +#ifndef DWC_DEVICE_ONLY // otg host mode. (HCD)
  6573. + /*
  6574. + * Initialize the HCD
  6575. + */
  6576. +#if 1 /*fscz*/
  6577. + /* force_host_mode */
  6578. + usbcfg.d32 = dwc_read_reg32(&dwc_otg_device->core_if->core_global_regs ->gusbcfg);
  6579. + usbcfg.b.force_host_mode = 1;
  6580. + dwc_write_reg32(&dwc_otg_device->core_if->core_global_regs ->gusbcfg, usbcfg.d32);
  6581. +#endif
  6582. + retval = dwc_otg_hcd_init(&_dev->dev, dwc_otg_device);
  6583. + if (retval != 0) {
  6584. + DWC_ERROR("dwc_otg_hcd_init failed\n");
  6585. + dwc_otg_device->hcd = NULL;
  6586. + goto fail;
  6587. + }
  6588. +#endif // DWC_DEVICE_ONLY
  6589. +
  6590. + /*
  6591. + * Enable the global interrupt after all the interrupt
  6592. + * handlers are installed.
  6593. + */
  6594. + dwc_otg_enable_global_interrupts( dwc_otg_device->core_if );
  6595. +#if 0 /*fscz*/
  6596. + usbcfg.d32 = dwc_read_reg32(&dwc_otg_device->core_if->core_global_regs ->gusbcfg);
  6597. + usbcfg.b.force_host_mode = 0;
  6598. + dwc_write_reg32(&dwc_otg_device->core_if->core_global_regs ->gusbcfg, usbcfg.d32);
  6599. +#endif
  6600. +
  6601. +
  6602. + return 0;
  6603. +
  6604. +fail:
  6605. + dwc_otg_driver_remove(_dev);
  6606. + return retval;
  6607. +}
  6608. +
  6609. +/**
  6610. + * This structure defines the methods to be called by a bus driver
  6611. + * during the lifecycle of a device on that bus. Both drivers and
  6612. + * devices are registered with a bus driver. The bus driver matches
  6613. + * devices to drivers based on information in the device and driver
  6614. + * structures.
  6615. + *
  6616. + * The probe function is called when the bus driver matches a device
  6617. + * to this driver. The remove function is called when a device is
  6618. + * unregistered with the bus driver.
  6619. + */
  6620. +struct platform_driver dwc_otg_driver = {
  6621. + .probe = dwc_otg_driver_probe,
  6622. + .remove = dwc_otg_driver_remove,
  6623. +// .suspend = dwc_otg_driver_suspend,
  6624. +// .resume = dwc_otg_driver_resume,
  6625. + .driver = {
  6626. + .name = dwc_driver_name,
  6627. + .owner = THIS_MODULE,
  6628. + },
  6629. +};
  6630. +EXPORT_SYMBOL(dwc_otg_driver);
  6631. +
  6632. +/**
  6633. + * This function is called when the dwc_otg_driver is installed with the
  6634. + * insmod command. It registers the dwc_otg_driver structure with the
  6635. + * appropriate bus driver. This will cause the dwc_otg_driver_probe function
  6636. + * to be called. In addition, the bus driver will automatically expose
  6637. + * attributes defined for the device and driver in the special sysfs file
  6638. + * system.
  6639. + *
  6640. + * @return
  6641. + */
  6642. +static int __init dwc_otg_init(void)
  6643. +{
  6644. + int retval = 0;
  6645. +
  6646. + printk(KERN_INFO "%s: version %s\n", dwc_driver_name, DWC_DRIVER_VERSION);
  6647. +
  6648. + // ifxmips setup
  6649. + retval = ifx_usb_hc_init(dwc_iomem_base, dwc_irq);
  6650. + if (retval < 0)
  6651. + {
  6652. + printk(KERN_ERR "%s retval=%d\n", __func__, retval);
  6653. + return retval;
  6654. + }
  6655. + dwc_otg_power_on(); // ifx only!!
  6656. +
  6657. +
  6658. + retval = platform_driver_register(&dwc_otg_driver);
  6659. +
  6660. + if (retval < 0) {
  6661. + printk(KERN_ERR "%s retval=%d\n", __func__, retval);
  6662. + goto error1;
  6663. + }
  6664. +
  6665. + retval = driver_create_file(&dwc_otg_driver.driver, &driver_attr_version);
  6666. + if (retval < 0)
  6667. + {
  6668. + printk(KERN_ERR "%s retval=%d\n", __func__, retval);
  6669. + goto error2;
  6670. + }
  6671. + retval = driver_create_file(&dwc_otg_driver.driver, &driver_attr_debuglevel);
  6672. + if (retval < 0)
  6673. + {
  6674. + printk(KERN_ERR "%s retval=%d\n", __func__, retval);
  6675. + goto error3;
  6676. + }
  6677. + return retval;
  6678. +
  6679. +
  6680. +error3:
  6681. + driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version);
  6682. +error2:
  6683. + driver_unregister(&dwc_otg_driver.driver);
  6684. +error1:
  6685. + ifx_usb_hc_remove();
  6686. + return retval;
  6687. +}
  6688. +module_init(dwc_otg_init);
  6689. +
  6690. +/**
  6691. + * This function is called when the driver is removed from the kernel
  6692. + * with the rmmod command. The driver unregisters itself with its bus
  6693. + * driver.
  6694. + *
  6695. + */
  6696. +static void __exit dwc_otg_cleanup(void)
  6697. +{
  6698. + printk(KERN_DEBUG "dwc_otg_cleanup()\n");
  6699. +
  6700. + driver_remove_file(&dwc_otg_driver.driver, &driver_attr_debuglevel);
  6701. + driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version);
  6702. +
  6703. + platform_driver_unregister(&dwc_otg_driver);
  6704. + ifx_usb_hc_remove();
  6705. +
  6706. + printk(KERN_INFO "%s module removed\n", dwc_driver_name);
  6707. +}
  6708. +module_exit(dwc_otg_cleanup);
  6709. +
  6710. +MODULE_DESCRIPTION(DWC_DRIVER_DESC);
  6711. +MODULE_AUTHOR("Synopsys Inc.");
  6712. +MODULE_LICENSE("GPL");
  6713. +
  6714. +module_param_named(otg_cap, dwc_otg_module_params.otg_cap, int, 0444);
  6715. +MODULE_PARM_DESC(otg_cap, "OTG Capabilities 0=HNP&SRP 1=SRP Only 2=None");
  6716. +module_param_named(opt, dwc_otg_module_params.opt, int, 0444);
  6717. +MODULE_PARM_DESC(opt, "OPT Mode");
  6718. +module_param_named(dma_enable, dwc_otg_module_params.dma_enable, int, 0444);
  6719. +MODULE_PARM_DESC(dma_enable, "DMA Mode 0=Slave 1=DMA enabled");
  6720. +module_param_named(dma_burst_size, dwc_otg_module_params.dma_burst_size, int, 0444);
  6721. +MODULE_PARM_DESC(dma_burst_size, "DMA Burst Size 1, 4, 8, 16, 32, 64, 128, 256");
  6722. +module_param_named(speed, dwc_otg_module_params.speed, int, 0444);
  6723. +MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed");
  6724. +module_param_named(host_support_fs_ls_low_power, dwc_otg_module_params.host_support_fs_ls_low_power, int, 0444);
  6725. +MODULE_PARM_DESC(host_support_fs_ls_low_power, "Support Low Power w/FS or LS 0=Support 1=Don't Support");
  6726. +module_param_named(host_ls_low_power_phy_clk, dwc_otg_module_params.host_ls_low_power_phy_clk, int, 0444);
  6727. +MODULE_PARM_DESC(host_ls_low_power_phy_clk, "Low Speed Low Power Clock 0=48Mhz 1=6Mhz");
  6728. +module_param_named(enable_dynamic_fifo, dwc_otg_module_params.enable_dynamic_fifo, int, 0444);
  6729. +MODULE_PARM_DESC(enable_dynamic_fifo, "0=cC Setting 1=Allow Dynamic Sizing");
  6730. +module_param_named(data_fifo_size, dwc_otg_module_params.data_fifo_size, int, 0444);
  6731. +MODULE_PARM_DESC(data_fifo_size, "Total number of words in the data FIFO memory 32-32768");
  6732. +module_param_named(dev_rx_fifo_size, dwc_otg_module_params.dev_rx_fifo_size, int, 0444);
  6733. +MODULE_PARM_DESC(dev_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
  6734. +module_param_named(dev_nperio_tx_fifo_size, dwc_otg_module_params.dev_nperio_tx_fifo_size, int, 0444);
  6735. +MODULE_PARM_DESC(dev_nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
  6736. +module_param_named(dev_perio_tx_fifo_size_1, dwc_otg_module_params.dev_perio_tx_fifo_size[0], int, 0444);
  6737. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_1, "Number of words in the periodic Tx FIFO 4-768");
  6738. +module_param_named(dev_perio_tx_fifo_size_2, dwc_otg_module_params.dev_perio_tx_fifo_size[1], int, 0444);
  6739. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_2, "Number of words in the periodic Tx FIFO 4-768");
  6740. +module_param_named(dev_perio_tx_fifo_size_3, dwc_otg_module_params.dev_perio_tx_fifo_size[2], int, 0444);
  6741. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_3, "Number of words in the periodic Tx FIFO 4-768");
  6742. +module_param_named(dev_perio_tx_fifo_size_4, dwc_otg_module_params.dev_perio_tx_fifo_size[3], int, 0444);
  6743. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_4, "Number of words in the periodic Tx FIFO 4-768");
  6744. +module_param_named(dev_perio_tx_fifo_size_5, dwc_otg_module_params.dev_perio_tx_fifo_size[4], int, 0444);
  6745. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_5, "Number of words in the periodic Tx FIFO 4-768");
  6746. +module_param_named(dev_perio_tx_fifo_size_6, dwc_otg_module_params.dev_perio_tx_fifo_size[5], int, 0444);
  6747. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_6, "Number of words in the periodic Tx FIFO 4-768");
  6748. +module_param_named(dev_perio_tx_fifo_size_7, dwc_otg_module_params.dev_perio_tx_fifo_size[6], int, 0444);
  6749. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_7, "Number of words in the periodic Tx FIFO 4-768");
  6750. +module_param_named(dev_perio_tx_fifo_size_8, dwc_otg_module_params.dev_perio_tx_fifo_size[7], int, 0444);
  6751. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_8, "Number of words in the periodic Tx FIFO 4-768");
  6752. +module_param_named(dev_perio_tx_fifo_size_9, dwc_otg_module_params.dev_perio_tx_fifo_size[8], int, 0444);
  6753. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_9, "Number of words in the periodic Tx FIFO 4-768");
  6754. +module_param_named(dev_perio_tx_fifo_size_10, dwc_otg_module_params.dev_perio_tx_fifo_size[9], int, 0444);
  6755. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_10, "Number of words in the periodic Tx FIFO 4-768");
  6756. +module_param_named(dev_perio_tx_fifo_size_11, dwc_otg_module_params.dev_perio_tx_fifo_size[10], int, 0444);
  6757. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_11, "Number of words in the periodic Tx FIFO 4-768");
  6758. +module_param_named(dev_perio_tx_fifo_size_12, dwc_otg_module_params.dev_perio_tx_fifo_size[11], int, 0444);
  6759. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_12, "Number of words in the periodic Tx FIFO 4-768");
  6760. +module_param_named(dev_perio_tx_fifo_size_13, dwc_otg_module_params.dev_perio_tx_fifo_size[12], int, 0444);
  6761. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_13, "Number of words in the periodic Tx FIFO 4-768");
  6762. +module_param_named(dev_perio_tx_fifo_size_14, dwc_otg_module_params.dev_perio_tx_fifo_size[13], int, 0444);
  6763. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_14, "Number of words in the periodic Tx FIFO 4-768");
  6764. +module_param_named(dev_perio_tx_fifo_size_15, dwc_otg_module_params.dev_perio_tx_fifo_size[14], int, 0444);
  6765. +MODULE_PARM_DESC(dev_perio_tx_fifo_size_15, "Number of words in the periodic Tx FIFO 4-768");
  6766. +module_param_named(host_rx_fifo_size, dwc_otg_module_params.host_rx_fifo_size, int, 0444);
  6767. +MODULE_PARM_DESC(host_rx_fifo_size, "Number of words in the Rx FIFO 16-32768");
  6768. +module_param_named(host_nperio_tx_fifo_size, dwc_otg_module_params.host_nperio_tx_fifo_size, int, 0444);
  6769. +MODULE_PARM_DESC(host_nperio_tx_fifo_size, "Number of words in the non-periodic Tx FIFO 16-32768");
  6770. +module_param_named(host_perio_tx_fifo_size, dwc_otg_module_params.host_perio_tx_fifo_size, int, 0444);
  6771. +MODULE_PARM_DESC(host_perio_tx_fifo_size, "Number of words in the host periodic Tx FIFO 16-32768");
  6772. +module_param_named(max_transfer_size, dwc_otg_module_params.max_transfer_size, int, 0444);
  6773. +/** @todo Set the max to 512K, modify checks */
  6774. +MODULE_PARM_DESC(max_transfer_size, "The maximum transfer size supported in bytes 2047-65535");
  6775. +module_param_named(max_packet_count, dwc_otg_module_params.max_packet_count, int, 0444);
  6776. +MODULE_PARM_DESC(max_packet_count, "The maximum number of packets in a transfer 15-511");
  6777. +module_param_named(host_channels, dwc_otg_module_params.host_channels, int, 0444);
  6778. +MODULE_PARM_DESC(host_channels, "The number of host channel registers to use 1-16");
  6779. +module_param_named(dev_endpoints, dwc_otg_module_params.dev_endpoints, int, 0444);
  6780. +MODULE_PARM_DESC(dev_endpoints, "The number of endpoints in addition to EP0 available for device mode 1-15");
  6781. +module_param_named(phy_type, dwc_otg_module_params.phy_type, int, 0444);
  6782. +MODULE_PARM_DESC(phy_type, "0=Reserved 1=UTMI+ 2=ULPI");
  6783. +module_param_named(phy_utmi_width, dwc_otg_module_params.phy_utmi_width, int, 0444);
  6784. +MODULE_PARM_DESC(phy_utmi_width, "Specifies the UTMI+ Data Width 8 or 16 bits");
  6785. +module_param_named(phy_ulpi_ddr, dwc_otg_module_params.phy_ulpi_ddr, int, 0444);
  6786. +MODULE_PARM_DESC(phy_ulpi_ddr, "ULPI at double or single data rate 0=Single 1=Double");
  6787. +module_param_named(phy_ulpi_ext_vbus, dwc_otg_module_params.phy_ulpi_ext_vbus, int, 0444);
  6788. +MODULE_PARM_DESC(phy_ulpi_ext_vbus, "ULPI PHY using internal or external vbus 0=Internal");
  6789. +module_param_named(i2c_enable, dwc_otg_module_params.i2c_enable, int, 0444);
  6790. +MODULE_PARM_DESC(i2c_enable, "FS PHY Interface");
  6791. +module_param_named(ulpi_fs_ls, dwc_otg_module_params.ulpi_fs_ls, int, 0444);
  6792. +MODULE_PARM_DESC(ulpi_fs_ls, "ULPI PHY FS/LS mode only");
  6793. +module_param_named(ts_dline, dwc_otg_module_params.ts_dline, int, 0444);
  6794. +MODULE_PARM_DESC(ts_dline, "Term select Dline pulsing for all PHYs");
  6795. +module_param_named(debug, g_dbg_lvl, int, 0444);
  6796. +MODULE_PARM_DESC(debug, "0");
  6797. +module_param_named(en_multiple_tx_fifo,
  6798. + dwc_otg_module_params.en_multiple_tx_fifo, int, 0444);
  6799. +MODULE_PARM_DESC(en_multiple_tx_fifo,
  6800. + "Dedicated Non Periodic Tx FIFOs 0=disabled 1=enabled");
  6801. +module_param_named(dev_tx_fifo_size_1,
  6802. + dwc_otg_module_params.dev_tx_fifo_size[0], int, 0444);
  6803. +MODULE_PARM_DESC(dev_tx_fifo_size_1, "Number of words in the Tx FIFO 4-768");
  6804. +module_param_named(dev_tx_fifo_size_2,
  6805. + dwc_otg_module_params.dev_tx_fifo_size[1], int, 0444);
  6806. +MODULE_PARM_DESC(dev_tx_fifo_size_2, "Number of words in the Tx FIFO 4-768");
  6807. +module_param_named(dev_tx_fifo_size_3,
  6808. + dwc_otg_module_params.dev_tx_fifo_size[2], int, 0444);
  6809. +MODULE_PARM_DESC(dev_tx_fifo_size_3, "Number of words in the Tx FIFO 4-768");
  6810. +module_param_named(dev_tx_fifo_size_4,
  6811. + dwc_otg_module_params.dev_tx_fifo_size[3], int, 0444);
  6812. +MODULE_PARM_DESC(dev_tx_fifo_size_4, "Number of words in the Tx FIFO 4-768");
  6813. +module_param_named(dev_tx_fifo_size_5,
  6814. + dwc_otg_module_params.dev_tx_fifo_size[4], int, 0444);
  6815. +MODULE_PARM_DESC(dev_tx_fifo_size_5, "Number of words in the Tx FIFO 4-768");
  6816. +module_param_named(dev_tx_fifo_size_6,
  6817. + dwc_otg_module_params.dev_tx_fifo_size[5], int, 0444);
  6818. +MODULE_PARM_DESC(dev_tx_fifo_size_6, "Number of words in the Tx FIFO 4-768");
  6819. +module_param_named(dev_tx_fifo_size_7,
  6820. + dwc_otg_module_params.dev_tx_fifo_size[6], int, 0444);
  6821. +MODULE_PARM_DESC(dev_tx_fifo_size_7, "Number of words in the Tx FIFO 4-768");
  6822. +module_param_named(dev_tx_fifo_size_8,
  6823. + dwc_otg_module_params.dev_tx_fifo_size[7], int, 0444);
  6824. +MODULE_PARM_DESC(dev_tx_fifo_size_8, "Number of words in the Tx FIFO 4-768");
  6825. +module_param_named(dev_tx_fifo_size_9,
  6826. + dwc_otg_module_params.dev_tx_fifo_size[8], int, 0444);
  6827. +MODULE_PARM_DESC(dev_tx_fifo_size_9, "Number of words in the Tx FIFO 4-768");
  6828. +module_param_named(dev_tx_fifo_size_10,
  6829. + dwc_otg_module_params.dev_tx_fifo_size[9], int, 0444);
  6830. +MODULE_PARM_DESC(dev_tx_fifo_size_10, "Number of words in the Tx FIFO 4-768");
  6831. +module_param_named(dev_tx_fifo_size_11,
  6832. + dwc_otg_module_params.dev_tx_fifo_size[10], int, 0444);
  6833. +MODULE_PARM_DESC(dev_tx_fifo_size_11, "Number of words in the Tx FIFO 4-768");
  6834. +module_param_named(dev_tx_fifo_size_12,
  6835. + dwc_otg_module_params.dev_tx_fifo_size[11], int, 0444);
  6836. +MODULE_PARM_DESC(dev_tx_fifo_size_12, "Number of words in the Tx FIFO 4-768");
  6837. +module_param_named(dev_tx_fifo_size_13,
  6838. + dwc_otg_module_params.dev_tx_fifo_size[12], int, 0444);
  6839. +MODULE_PARM_DESC(dev_tx_fifo_size_13, "Number of words in the Tx FIFO 4-768");
  6840. +module_param_named(dev_tx_fifo_size_14,
  6841. + dwc_otg_module_params.dev_tx_fifo_size[13], int, 0444);
  6842. +MODULE_PARM_DESC(dev_tx_fifo_size_14, "Number of words in the Tx FIFO 4-768");
  6843. +module_param_named(dev_tx_fifo_size_15,
  6844. + dwc_otg_module_params.dev_tx_fifo_size[14], int, 0444);
  6845. +MODULE_PARM_DESC(dev_tx_fifo_size_15, "Number of words in the Tx FIFO 4-768");
  6846. +module_param_named(thr_ctl, dwc_otg_module_params.thr_ctl, int, 0444);
  6847. +MODULE_PARM_DESC(thr_ctl, "Thresholding enable flag bit"
  6848. + "0 - non ISO Tx thr., 1 - ISO Tx thr., 2 - Rx thr.- bit 0=disabled 1=enabled");
  6849. +module_param_named(tx_thr_length, dwc_otg_module_params.tx_thr_length, int, 0444);
  6850. +MODULE_PARM_DESC(tx_thr_length, "Tx Threshold length in 32 bit DWORDs");
  6851. +module_param_named(rx_thr_length, dwc_otg_module_params.rx_thr_length, int, 0444);
  6852. +MODULE_PARM_DESC(rx_thr_length, "Rx Threshold length in 32 bit DWORDs");
  6853. +module_param_named (iomem_base, dwc_iomem_base, ulong, 0444);
  6854. +MODULE_PARM_DESC (dwc_iomem_base, "The base address of the DWC_OTG register.");
  6855. +module_param_named (irq, dwc_irq, int, 0444);
  6856. +MODULE_PARM_DESC (dwc_irq, "The interrupt number");
  6857. +
  6858. +/** @page "Module Parameters"
  6859. + *
  6860. + * The following parameters may be specified when starting the module.
  6861. + * These parameters define how the DWC_otg controller should be
  6862. + * configured. Parameter values are passed to the CIL initialization
  6863. + * function dwc_otg_cil_init
  6864. + *
  6865. + * Example: <code>modprobe dwc_otg speed=1 otg_cap=1</code>
  6866. + *
  6867. +
  6868. + <table>
  6869. + <tr><td>Parameter Name</td><td>Meaning</td></tr>
  6870. +
  6871. + <tr>
  6872. + <td>otg_cap</td>
  6873. + <td>Specifies the OTG capabilities. The driver will automatically detect the
  6874. + value for this parameter if none is specified.
  6875. + - 0: HNP and SRP capable (default, if available)
  6876. + - 1: SRP Only capable
  6877. + - 2: No HNP/SRP capable
  6878. + </td></tr>
  6879. +
  6880. + <tr>
  6881. + <td>dma_enable</td>
  6882. + <td>Specifies whether to use slave or DMA mode for accessing the data FIFOs.
  6883. + The driver will automatically detect the value for this parameter if none is
  6884. + specified.
  6885. + - 0: Slave
  6886. + - 1: DMA (default, if available)
  6887. + </td></tr>
  6888. +
  6889. + <tr>
  6890. + <td>dma_burst_size</td>
  6891. + <td>The DMA Burst size (applicable only for External DMA Mode).
  6892. + - Values: 1, 4, 8 16, 32, 64, 128, 256 (default 32)
  6893. + </td></tr>
  6894. +
  6895. + <tr>
  6896. + <td>speed</td>
  6897. + <td>Specifies the maximum speed of operation in host and device mode. The
  6898. + actual speed depends on the speed of the attached device and the value of
  6899. + phy_type.
  6900. + - 0: High Speed (default)
  6901. + - 1: Full Speed
  6902. + </td></tr>
  6903. +
  6904. + <tr>
  6905. + <td>host_support_fs_ls_low_power</td>
  6906. + <td>Specifies whether low power mode is supported when attached to a Full
  6907. + Speed or Low Speed device in host mode.
  6908. + - 0: Don't support low power mode (default)
  6909. + - 1: Support low power mode
  6910. + </td></tr>
  6911. +
  6912. + <tr>
  6913. + <td>host_ls_low_power_phy_clk</td>
  6914. + <td>Specifies the PHY clock rate in low power mode when connected to a Low
  6915. + Speed device in host mode. This parameter is applicable only if
  6916. + HOST_SUPPORT_FS_LS_LOW_POWER is enabled.
  6917. + - 0: 48 MHz (default)
  6918. + - 1: 6 MHz
  6919. + </td></tr>
  6920. +
  6921. + <tr>
  6922. + <td>enable_dynamic_fifo</td>
  6923. + <td> Specifies whether FIFOs may be resized by the driver software.
  6924. + - 0: Use cC FIFO size parameters
  6925. + - 1: Allow dynamic FIFO sizing (default)
  6926. + </td></tr>
  6927. +
  6928. + <tr>
  6929. + <td>data_fifo_size</td>
  6930. + <td>Total number of 4-byte words in the data FIFO memory. This memory
  6931. + includes the Rx FIFO, non-periodic Tx FIFO, and periodic Tx FIFOs.
  6932. + - Values: 32 to 32768 (default 8192)
  6933. +
  6934. + Note: The total FIFO memory depth in the FPGA configuration is 8192.
  6935. + </td></tr>
  6936. +
  6937. + <tr>
  6938. + <td>dev_rx_fifo_size</td>
  6939. + <td>Number of 4-byte words in the Rx FIFO in device mode when dynamic
  6940. + FIFO sizing is enabled.
  6941. + - Values: 16 to 32768 (default 1064)
  6942. + </td></tr>
  6943. +
  6944. + <tr>
  6945. + <td>dev_nperio_tx_fifo_size</td>
  6946. + <td>Number of 4-byte words in the non-periodic Tx FIFO in device mode when
  6947. + dynamic FIFO sizing is enabled.
  6948. + - Values: 16 to 32768 (default 1024)
  6949. + </td></tr>
  6950. +
  6951. + <tr>
  6952. + <td>dev_perio_tx_fifo_size_n (n = 1 to 15)</td>
  6953. + <td>Number of 4-byte words in each of the periodic Tx FIFOs in device mode
  6954. + when dynamic FIFO sizing is enabled.
  6955. + - Values: 4 to 768 (default 256)
  6956. + </td></tr>
  6957. +
  6958. + <tr>
  6959. + <td>host_rx_fifo_size</td>
  6960. + <td>Number of 4-byte words in the Rx FIFO in host mode when dynamic FIFO
  6961. + sizing is enabled.
  6962. + - Values: 16 to 32768 (default 1024)
  6963. + </td></tr>
  6964. +
  6965. + <tr>
  6966. + <td>host_nperio_tx_fifo_size</td>
  6967. + <td>Number of 4-byte words in the non-periodic Tx FIFO in host mode when
  6968. + dynamic FIFO sizing is enabled in the core.
  6969. + - Values: 16 to 32768 (default 1024)
  6970. + </td></tr>
  6971. +
  6972. + <tr>
  6973. + <td>host_perio_tx_fifo_size</td>
  6974. + <td>Number of 4-byte words in the host periodic Tx FIFO when dynamic FIFO
  6975. + sizing is enabled.
  6976. + - Values: 16 to 32768 (default 1024)
  6977. + </td></tr>
  6978. +
  6979. + <tr>
  6980. + <td>max_transfer_size</td>
  6981. + <td>The maximum transfer size supported in bytes.
  6982. + - Values: 2047 to 65,535 (default 65,535)
  6983. + </td></tr>
  6984. +
  6985. + <tr>
  6986. + <td>max_packet_count</td>
  6987. + <td>The maximum number of packets in a transfer.
  6988. + - Values: 15 to 511 (default 511)
  6989. + </td></tr>
  6990. +
  6991. + <tr>
  6992. + <td>host_channels</td>
  6993. + <td>The number of host channel registers to use.
  6994. + - Values: 1 to 16 (default 12)
  6995. +
  6996. + Note: The FPGA configuration supports a maximum of 12 host channels.
  6997. + </td></tr>
  6998. +
  6999. + <tr>
  7000. + <td>dev_endpoints</td>
  7001. + <td>The number of endpoints in addition to EP0 available for device mode
  7002. + operations.
  7003. + - Values: 1 to 15 (default 6 IN and OUT)
  7004. +
  7005. + Note: The FPGA configuration supports a maximum of 6 IN and OUT endpoints in
  7006. + addition to EP0.
  7007. + </td></tr>
  7008. +
  7009. + <tr>
  7010. + <td>phy_type</td>
  7011. + <td>Specifies the type of PHY interface to use. By default, the driver will
  7012. + automatically detect the phy_type.
  7013. + - 0: Full Speed
  7014. + - 1: UTMI+ (default, if available)
  7015. + - 2: ULPI
  7016. + </td></tr>
  7017. +
  7018. + <tr>
  7019. + <td>phy_utmi_width</td>
  7020. + <td>Specifies the UTMI+ Data Width. This parameter is applicable for a
  7021. + phy_type of UTMI+. Also, this parameter is applicable only if the
  7022. + OTG_HSPHY_WIDTH cC parameter was set to "8 and 16 bits", meaning that the
  7023. + core has been configured to work at either data path width.
  7024. + - Values: 8 or 16 bits (default 16)
  7025. + </td></tr>
  7026. +
  7027. + <tr>
  7028. + <td>phy_ulpi_ddr</td>
  7029. + <td>Specifies whether the ULPI operates at double or single data rate. This
  7030. + parameter is only applicable if phy_type is ULPI.
  7031. + - 0: single data rate ULPI interface with 8 bit wide data bus (default)
  7032. + - 1: double data rate ULPI interface with 4 bit wide data bus
  7033. + </td></tr>
  7034. +
  7035. + <tr>
  7036. + <td>i2c_enable</td>
  7037. + <td>Specifies whether to use the I2C interface for full speed PHY. This
  7038. + parameter is only applicable if PHY_TYPE is FS.
  7039. + - 0: Disabled (default)
  7040. + - 1: Enabled
  7041. + </td></tr>
  7042. +
  7043. + <tr>
  7044. + <td>otg_en_multiple_tx_fifo</td>
  7045. + <td>Specifies whether dedicatedto tx fifos are enabled for non periodic IN EPs.
  7046. + The driver will automatically detect the value for this parameter if none is
  7047. + specified.
  7048. + - 0: Disabled
  7049. + - 1: Enabled (default, if available)
  7050. + </td></tr>
  7051. +
  7052. + <tr>
  7053. + <td>dev_tx_fifo_size_n (n = 1 to 15)</td>
  7054. + <td>Number of 4-byte words in each of the Tx FIFOs in device mode
  7055. + when dynamic FIFO sizing is enabled.
  7056. + - Values: 4 to 768 (default 256)
  7057. + </td></tr>
  7058. +
  7059. +*/
  7060. diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.h b/drivers/usb/dwc_otg/dwc_otg_driver.h
  7061. new file mode 100644
  7062. index 0000000..7e6940d
  7063. --- /dev/null
  7064. +++ b/drivers/usb/dwc_otg/dwc_otg_driver.h
  7065. @@ -0,0 +1,84 @@
  7066. +/* ==========================================================================
  7067. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_driver.h $
  7068. + * $Revision: 1.1.1.1 $
  7069. + * $Date: 2009-04-17 06:15:34 $
  7070. + * $Change: 510275 $
  7071. + *
  7072. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  7073. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  7074. + * otherwise expressly agreed to in writing between Synopsys and you.
  7075. + *
  7076. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  7077. + * any End User Software License Agreement or Agreement for Licensed Product
  7078. + * with Synopsys or any supplement thereto. You are permitted to use and
  7079. + * redistribute this Software in source and binary forms, with or without
  7080. + * modification, provided that redistributions of source code must retain this
  7081. + * notice. You may not view, use, disclose, copy or distribute this file or
  7082. + * any information contained herein except pursuant to this license grant from
  7083. + * Synopsys. If you do not agree with this notice, including the disclaimer
  7084. + * below, then you are not authorized to use the Software.
  7085. + *
  7086. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  7087. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  7088. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  7089. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  7090. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  7091. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  7092. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  7093. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  7094. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  7095. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  7096. + * DAMAGE.
  7097. + * ========================================================================== */
  7098. +
  7099. +#if !defined(__DWC_OTG_DRIVER_H__)
  7100. +#define __DWC_OTG_DRIVER_H__
  7101. +
  7102. +/** @file
  7103. + * This file contains the interface to the Linux driver.
  7104. + */
  7105. +#include "dwc_otg_cil.h"
  7106. +
  7107. +/* Type declarations */
  7108. +struct dwc_otg_pcd;
  7109. +struct dwc_otg_hcd;
  7110. +
  7111. +/**
  7112. + * This structure is a wrapper that encapsulates the driver components used to
  7113. + * manage a single DWC_otg controller.
  7114. + */
  7115. +typedef struct dwc_otg_device
  7116. +{
  7117. + /** Base address returned from ioremap() */
  7118. + void *base;
  7119. +
  7120. + /** Pointer to the core interface structure. */
  7121. + dwc_otg_core_if_t *core_if;
  7122. +
  7123. + /** Register offset for Diagnostic API.*/
  7124. + uint32_t reg_offset;
  7125. +
  7126. + /** Pointer to the PCD structure. */
  7127. + struct dwc_otg_pcd *pcd;
  7128. +
  7129. + /** Pointer to the HCD structure. */
  7130. + struct dwc_otg_hcd *hcd;
  7131. +
  7132. + /** Flag to indicate whether the common IRQ handler is installed. */
  7133. + uint8_t common_irq_installed;
  7134. +
  7135. + /** Interrupt request number. */
  7136. + unsigned int irq;
  7137. +
  7138. + /** Physical address of Control and Status registers, used by
  7139. + * release_mem_region().
  7140. + */
  7141. + resource_size_t phys_addr;
  7142. +
  7143. + /** Length of memory region, used by release_mem_region(). */
  7144. + unsigned long base_len;
  7145. +} dwc_otg_device_t;
  7146. +
  7147. +//#define dev_dbg(fake, format, arg...) printk(KERN_CRIT __FILE__ ":%d: " format "\n" , __LINE__, ## arg)
  7148. +
  7149. +#endif
  7150. diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c
  7151. new file mode 100644
  7152. index 0000000..ad6bc72
  7153. --- /dev/null
  7154. +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c
  7155. @@ -0,0 +1,2870 @@
  7156. +/* ==========================================================================
  7157. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd.c $
  7158. + * $Revision: 1.1.1.1 $
  7159. + * $Date: 2009-04-17 06:15:34 $
  7160. + * $Change: 631780 $
  7161. + *
  7162. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  7163. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  7164. + * otherwise expressly agreed to in writing between Synopsys and you.
  7165. + *
  7166. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  7167. + * any End User Software License Agreement or Agreement for Licensed Product
  7168. + * with Synopsys or any supplement thereto. You are permitted to use and
  7169. + * redistribute this Software in source and binary forms, with or without
  7170. + * modification, provided that redistributions of source code must retain this
  7171. + * notice. You may not view, use, disclose, copy or distribute this file or
  7172. + * any information contained herein except pursuant to this license grant from
  7173. + * Synopsys. If you do not agree with this notice, including the disclaimer
  7174. + * below, then you are not authorized to use the Software.
  7175. + *
  7176. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  7177. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  7178. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  7179. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  7180. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  7181. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  7182. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  7183. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  7184. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  7185. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  7186. + * DAMAGE.
  7187. + * ========================================================================== */
  7188. +#ifndef DWC_DEVICE_ONLY
  7189. +
  7190. +/**
  7191. + * @file
  7192. + *
  7193. + * This file contains the implementation of the HCD. In Linux, the HCD
  7194. + * implements the hc_driver API.
  7195. + */
  7196. +#include <linux/kernel.h>
  7197. +#include <linux/module.h>
  7198. +#include <linux/moduleparam.h>
  7199. +#include <linux/init.h>
  7200. +
  7201. +#include <linux/device.h>
  7202. +
  7203. +#include <linux/errno.h>
  7204. +#include <linux/list.h>
  7205. +#include <linux/interrupt.h>
  7206. +#include <linux/string.h>
  7207. +
  7208. +#include <linux/dma-mapping.h>
  7209. +
  7210. +#include "dwc_otg_driver.h"
  7211. +#include "dwc_otg_hcd.h"
  7212. +#include "dwc_otg_regs.h"
  7213. +
  7214. +#include <asm/irq.h>
  7215. +#include "dwc_otg_ifx.h" // for Infineon platform specific.
  7216. +extern atomic_t release_later;
  7217. +
  7218. +static u64 dma_mask = DMA_BIT_MASK(32);
  7219. +
  7220. +static const char dwc_otg_hcd_name [] = "dwc_otg_hcd";
  7221. +static const struct hc_driver dwc_otg_hc_driver =
  7222. +{
  7223. + .description = dwc_otg_hcd_name,
  7224. + .product_desc = "DWC OTG Controller",
  7225. + .hcd_priv_size = sizeof(dwc_otg_hcd_t),
  7226. + .irq = dwc_otg_hcd_irq,
  7227. + .flags = HCD_MEMORY | HCD_USB2,
  7228. + //.reset =
  7229. + .start = dwc_otg_hcd_start,
  7230. + //.suspend =
  7231. + //.resume =
  7232. + .stop = dwc_otg_hcd_stop,
  7233. + .urb_enqueue = dwc_otg_hcd_urb_enqueue,
  7234. + .urb_dequeue = dwc_otg_hcd_urb_dequeue,
  7235. + .endpoint_disable = dwc_otg_hcd_endpoint_disable,
  7236. + .get_frame_number = dwc_otg_hcd_get_frame_number,
  7237. + .hub_status_data = dwc_otg_hcd_hub_status_data,
  7238. + .hub_control = dwc_otg_hcd_hub_control,
  7239. + //.hub_suspend =
  7240. + //.hub_resume =
  7241. +};
  7242. +
  7243. +
  7244. +/**
  7245. + * Work queue function for starting the HCD when A-Cable is connected.
  7246. + * The dwc_otg_hcd_start() must be called in a process context.
  7247. + */
  7248. +static void hcd_start_func(struct work_struct *work)
  7249. +{
  7250. + struct dwc_otg_hcd *priv =
  7251. + container_of(work, struct dwc_otg_hcd, start_work);
  7252. + struct usb_hcd *usb_hcd = (struct usb_hcd *)priv->_p;
  7253. + DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, usb_hcd);
  7254. + if (usb_hcd) {
  7255. + dwc_otg_hcd_start(usb_hcd);
  7256. + }
  7257. +}
  7258. +
  7259. +
  7260. +/**
  7261. + * HCD Callback function for starting the HCD when A-Cable is
  7262. + * connected.
  7263. + *
  7264. + * @param _p void pointer to the <code>struct usb_hcd</code>
  7265. + */
  7266. +static int32_t dwc_otg_hcd_start_cb(void *_p)
  7267. +{
  7268. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_p);
  7269. + dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
  7270. + hprt0_data_t hprt0;
  7271. + if (core_if->op_state == B_HOST) {
  7272. + /*
  7273. + * Reset the port. During a HNP mode switch the reset
  7274. + * needs to occur within 1ms and have a duration of at
  7275. + * least 50ms.
  7276. + */
  7277. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  7278. + hprt0.b.prtrst = 1;
  7279. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  7280. + ((struct usb_hcd *)_p)->self.is_b_host = 1;
  7281. + } else {
  7282. + ((struct usb_hcd *)_p)->self.is_b_host = 0;
  7283. + }
  7284. + /* Need to start the HCD in a non-interrupt context. */
  7285. + INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func);
  7286. + dwc_otg_hcd->_p = _p;
  7287. + schedule_work(&dwc_otg_hcd->start_work);
  7288. + return 1;
  7289. +}
  7290. +
  7291. +
  7292. +/**
  7293. + * HCD Callback function for stopping the HCD.
  7294. + *
  7295. + * @param _p void pointer to the <code>struct usb_hcd</code>
  7296. + */
  7297. +static int32_t dwc_otg_hcd_stop_cb( void *_p )
  7298. +{
  7299. + struct usb_hcd *usb_hcd = (struct usb_hcd *)_p;
  7300. + DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
  7301. + dwc_otg_hcd_stop( usb_hcd );
  7302. + return 1;
  7303. +}
  7304. +static void del_xfer_timers(dwc_otg_hcd_t *_hcd)
  7305. +{
  7306. +#ifdef DEBUG
  7307. + int i;
  7308. + int num_channels = _hcd->core_if->core_params->host_channels;
  7309. + for (i = 0; i < num_channels; i++) {
  7310. + del_timer(&_hcd->core_if->hc_xfer_timer[i]);
  7311. + }
  7312. +#endif /* */
  7313. +}
  7314. +
  7315. +static void del_timers(dwc_otg_hcd_t *_hcd)
  7316. +{
  7317. + del_xfer_timers(_hcd);
  7318. + del_timer(&_hcd->conn_timer);
  7319. +}
  7320. +
  7321. +/**
  7322. + * Processes all the URBs in a single list of QHs. Completes them with
  7323. + * -ETIMEDOUT and frees the QTD.
  7324. + */
  7325. +static void kill_urbs_in_qh_list(dwc_otg_hcd_t * _hcd,
  7326. + struct list_head *_qh_list)
  7327. +{
  7328. + struct list_head *qh_item;
  7329. + dwc_otg_qh_t *qh;
  7330. + struct list_head *qtd_item;
  7331. + dwc_otg_qtd_t *qtd;
  7332. +
  7333. + list_for_each(qh_item, _qh_list) {
  7334. + qh = list_entry(qh_item, dwc_otg_qh_t, qh_list_entry);
  7335. + for (qtd_item = qh->qtd_list.next; qtd_item != &qh->qtd_list;
  7336. + qtd_item = qh->qtd_list.next) {
  7337. + qtd = list_entry(qtd_item, dwc_otg_qtd_t, qtd_list_entry);
  7338. + if (qtd->urb != NULL) {
  7339. + dwc_otg_hcd_complete_urb(_hcd, qtd->urb,-ETIMEDOUT);
  7340. + }
  7341. + dwc_otg_hcd_qtd_remove_and_free(qtd);
  7342. + }
  7343. + }
  7344. +}
  7345. +
  7346. +/**
  7347. + * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
  7348. + * and periodic schedules. The QTD associated with each URB is removed from
  7349. + * the schedule and freed. This function may be called when a disconnect is
  7350. + * detected or when the HCD is being stopped.
  7351. + */
  7352. +static void kill_all_urbs(dwc_otg_hcd_t *_hcd)
  7353. +{
  7354. + kill_urbs_in_qh_list(_hcd, &_hcd->non_periodic_sched_deferred);
  7355. + kill_urbs_in_qh_list(_hcd, &_hcd->non_periodic_sched_inactive);
  7356. + kill_urbs_in_qh_list(_hcd, &_hcd->non_periodic_sched_active);
  7357. + kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_inactive);
  7358. + kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_ready);
  7359. + kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_assigned);
  7360. + kill_urbs_in_qh_list(_hcd, &_hcd->periodic_sched_queued);
  7361. +}
  7362. +
  7363. +/**
  7364. + * HCD Callback function for disconnect of the HCD.
  7365. + *
  7366. + * @param _p void pointer to the <code>struct usb_hcd</code>
  7367. + */
  7368. +static int32_t dwc_otg_hcd_disconnect_cb( void *_p )
  7369. +{
  7370. + gintsts_data_t intr;
  7371. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_p);
  7372. +
  7373. + DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
  7374. +
  7375. + /*
  7376. + * Set status flags for the hub driver.
  7377. + */
  7378. + dwc_otg_hcd->flags.b.port_connect_status_change = 1;
  7379. + dwc_otg_hcd->flags.b.port_connect_status = 0;
  7380. +
  7381. + /*
  7382. + * Shutdown any transfers in process by clearing the Tx FIFO Empty
  7383. + * interrupt mask and status bits and disabling subsequent host
  7384. + * channel interrupts.
  7385. + */
  7386. + intr.d32 = 0;
  7387. + intr.b.nptxfempty = 1;
  7388. + intr.b.ptxfempty = 1;
  7389. + intr.b.hcintr = 1;
  7390. + dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintmsk, intr.d32, 0);
  7391. + dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintsts, intr.d32, 0);
  7392. +
  7393. + del_timers(dwc_otg_hcd);
  7394. +
  7395. + /*
  7396. + * Turn off the vbus power only if the core has transitioned to device
  7397. + * mode. If still in host mode, need to keep power on to detect a
  7398. + * reconnection.
  7399. + */
  7400. + if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) {
  7401. + if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) {
  7402. + hprt0_data_t hprt0 = { .d32=0 };
  7403. + DWC_PRINT("Disconnect: PortPower off\n");
  7404. + hprt0.b.prtpwr = 0;
  7405. + dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
  7406. + }
  7407. +
  7408. + dwc_otg_disable_host_interrupts( dwc_otg_hcd->core_if );
  7409. + }
  7410. +
  7411. + /* Respond with an error status to all URBs in the schedule. */
  7412. + kill_all_urbs(dwc_otg_hcd);
  7413. +
  7414. + if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) {
  7415. + /* Clean up any host channels that were in use. */
  7416. + int num_channels;
  7417. + int i;
  7418. + dwc_hc_t *channel;
  7419. + dwc_otg_hc_regs_t *hc_regs;
  7420. + hcchar_data_t hcchar;
  7421. +
  7422. + num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
  7423. +
  7424. + if (!dwc_otg_hcd->core_if->dma_enable) {
  7425. + /* Flush out any channel requests in slave mode. */
  7426. + for (i = 0; i < num_channels; i++) {
  7427. + channel = dwc_otg_hcd->hc_ptr_array[i];
  7428. + if (list_empty(&channel->hc_list_entry)) {
  7429. + hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[i];
  7430. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  7431. + if (hcchar.b.chen) {
  7432. + hcchar.b.chen = 0;
  7433. + hcchar.b.chdis = 1;
  7434. + hcchar.b.epdir = 0;
  7435. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  7436. + }
  7437. + }
  7438. + }
  7439. + }
  7440. +
  7441. + for (i = 0; i < num_channels; i++) {
  7442. + channel = dwc_otg_hcd->hc_ptr_array[i];
  7443. + if (list_empty(&channel->hc_list_entry)) {
  7444. + hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[i];
  7445. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  7446. + if (hcchar.b.chen) {
  7447. + /* Halt the channel. */
  7448. + hcchar.b.chdis = 1;
  7449. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  7450. + }
  7451. +
  7452. + dwc_otg_hc_cleanup(dwc_otg_hcd->core_if, channel);
  7453. + list_add_tail(&channel->hc_list_entry,
  7454. + &dwc_otg_hcd->free_hc_list);
  7455. + }
  7456. + }
  7457. + }
  7458. +
  7459. + /* A disconnect will end the session so the B-Device is no
  7460. + * longer a B-host. */
  7461. + ((struct usb_hcd *)_p)->self.is_b_host = 0;
  7462. +
  7463. + return 1;
  7464. +}
  7465. +
  7466. +/**
  7467. + * Connection timeout function. An OTG host is required to display a
  7468. + * message if the device does not connect within 10 seconds.
  7469. + */
  7470. +void dwc_otg_hcd_connect_timeout( unsigned long _ptr )
  7471. +{
  7472. + DWC_DEBUGPL(DBG_HCDV, "%s(%x)\n", __func__, (int)_ptr);
  7473. + DWC_PRINT( "Connect Timeout\n");
  7474. + DWC_ERROR( "Device Not Connected/Responding\n" );
  7475. +}
  7476. +
  7477. +/**
  7478. + * Start the connection timer. An OTG host is required to display a
  7479. + * message if the device does not connect within 10 seconds. The
  7480. + * timer is deleted if a port connect interrupt occurs before the
  7481. + * timer expires.
  7482. + */
  7483. +static void dwc_otg_hcd_start_connect_timer( dwc_otg_hcd_t *_hcd)
  7484. +{
  7485. + init_timer( &_hcd->conn_timer );
  7486. + _hcd->conn_timer.function = dwc_otg_hcd_connect_timeout;
  7487. + _hcd->conn_timer.data = (unsigned long)0;
  7488. + _hcd->conn_timer.expires = jiffies + (HZ*10);
  7489. + add_timer( &_hcd->conn_timer );
  7490. +}
  7491. +
  7492. +/**
  7493. + * HCD Callback function for disconnect of the HCD.
  7494. + *
  7495. + * @param _p void pointer to the <code>struct usb_hcd</code>
  7496. + */
  7497. +static int32_t dwc_otg_hcd_session_start_cb( void *_p )
  7498. +{
  7499. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_p);
  7500. + DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p);
  7501. + dwc_otg_hcd_start_connect_timer( dwc_otg_hcd );
  7502. + return 1;
  7503. +}
  7504. +
  7505. +/**
  7506. + * HCD Callback structure for handling mode switching.
  7507. + */
  7508. +static dwc_otg_cil_callbacks_t hcd_cil_callbacks = {
  7509. + .start = dwc_otg_hcd_start_cb,
  7510. + .stop = dwc_otg_hcd_stop_cb,
  7511. + .disconnect = dwc_otg_hcd_disconnect_cb,
  7512. + .session_start = dwc_otg_hcd_session_start_cb,
  7513. + .p = 0,
  7514. +};
  7515. +
  7516. +
  7517. +/**
  7518. + * Reset tasklet function
  7519. + */
  7520. +static void reset_tasklet_func (unsigned long data)
  7521. +{
  7522. + dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t*)data;
  7523. + dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
  7524. + hprt0_data_t hprt0;
  7525. +
  7526. + DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n");
  7527. +
  7528. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  7529. + hprt0.b.prtrst = 1;
  7530. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  7531. + mdelay (60);
  7532. +
  7533. + hprt0.b.prtrst = 0;
  7534. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  7535. + dwc_otg_hcd->flags.b.port_reset_change = 1;
  7536. +
  7537. + return;
  7538. +}
  7539. +
  7540. +static struct tasklet_struct reset_tasklet = {
  7541. + .next = NULL,
  7542. + .state = 0,
  7543. + .count = ATOMIC_INIT(0),
  7544. + .func = reset_tasklet_func,
  7545. + .data = 0,
  7546. +};
  7547. +
  7548. +/**
  7549. + * Initializes the HCD. This function allocates memory for and initializes the
  7550. + * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
  7551. + * USB bus with the core and calls the hc_driver->start() function. It returns
  7552. + * a negative error on failure.
  7553. + */
  7554. +int init_hcd_usecs(dwc_otg_hcd_t *_hcd);
  7555. +
  7556. +int __devinit dwc_otg_hcd_init(struct device *_dev, dwc_otg_device_t * dwc_otg_device)
  7557. +{
  7558. + struct usb_hcd *hcd = NULL;
  7559. + dwc_otg_hcd_t *dwc_otg_hcd = NULL;
  7560. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  7561. +
  7562. + int num_channels;
  7563. + int i;
  7564. + dwc_hc_t *channel;
  7565. +
  7566. + int retval = 0;
  7567. +
  7568. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
  7569. +
  7570. + /*
  7571. + * Allocate memory for the base HCD plus the DWC OTG HCD.
  7572. + * Initialize the base HCD.
  7573. + */
  7574. + hcd = usb_create_hcd(&dwc_otg_hc_driver, _dev, dev_name(_dev));
  7575. + if (hcd == NULL) {
  7576. + retval = -ENOMEM;
  7577. + goto error1;
  7578. + }
  7579. + dev_set_drvdata(_dev, dwc_otg_device); /* fscz restore */
  7580. + hcd->regs = otg_dev->base;
  7581. + hcd->rsrc_start = (int)otg_dev->base;
  7582. +
  7583. + hcd->self.otg_port = 1;
  7584. +
  7585. + /* Initialize the DWC OTG HCD. */
  7586. + dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
  7587. + dwc_otg_hcd->core_if = otg_dev->core_if;
  7588. + otg_dev->hcd = dwc_otg_hcd;
  7589. +
  7590. + /* Register the HCD CIL Callbacks */
  7591. + dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if,
  7592. + &hcd_cil_callbacks, hcd);
  7593. +
  7594. + /* Initialize the non-periodic schedule. */
  7595. + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive);
  7596. + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active);
  7597. + INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_deferred);
  7598. +
  7599. + /* Initialize the periodic schedule. */
  7600. + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive);
  7601. + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready);
  7602. + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned);
  7603. + INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued);
  7604. +
  7605. + /*
  7606. + * Create a host channel descriptor for each host channel implemented
  7607. + * in the controller. Initialize the channel descriptor array.
  7608. + */
  7609. + INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list);
  7610. + num_channels = dwc_otg_hcd->core_if->core_params->host_channels;
  7611. + for (i = 0; i < num_channels; i++) {
  7612. + channel = kmalloc(sizeof(dwc_hc_t), GFP_KERNEL);
  7613. + if (channel == NULL) {
  7614. + retval = -ENOMEM;
  7615. + DWC_ERROR("%s: host channel allocation failed\n", __func__);
  7616. + goto error2;
  7617. + }
  7618. + memset(channel, 0, sizeof(dwc_hc_t));
  7619. + channel->hc_num = i;
  7620. + dwc_otg_hcd->hc_ptr_array[i] = channel;
  7621. +#ifdef DEBUG
  7622. + init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]);
  7623. +#endif
  7624. +
  7625. + DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, channel);
  7626. + }
  7627. +
  7628. + /* Initialize the Connection timeout timer. */
  7629. + init_timer( &dwc_otg_hcd->conn_timer );
  7630. +
  7631. + /* Initialize reset tasklet. */
  7632. + reset_tasklet.data = (unsigned long) dwc_otg_hcd;
  7633. + dwc_otg_hcd->reset_tasklet = &reset_tasklet;
  7634. +
  7635. + /* Set device flags indicating whether the HCD supports DMA. */
  7636. + if (otg_dev->core_if->dma_enable) {
  7637. + DWC_PRINT("Using DMA mode\n");
  7638. + //_dev->dma_mask = (void *)~0;
  7639. + //_dev->coherent_dma_mask = ~0;
  7640. + _dev->dma_mask = &dma_mask;
  7641. + _dev->coherent_dma_mask = DMA_BIT_MASK(32);
  7642. + } else {
  7643. + DWC_PRINT("Using Slave mode\n");
  7644. + _dev->dma_mask = (void *)0;
  7645. + _dev->coherent_dma_mask = 0;
  7646. + }
  7647. +
  7648. + init_hcd_usecs(dwc_otg_hcd);
  7649. + /*
  7650. + * Finish generic HCD initialization and start the HCD. This function
  7651. + * allocates the DMA buffer pool, registers the USB bus, requests the
  7652. + * IRQ line, and calls dwc_otg_hcd_start method.
  7653. + */
  7654. + retval = usb_add_hcd(hcd, otg_dev->irq, IRQF_SHARED);
  7655. + if (retval < 0) {
  7656. + goto error2;
  7657. + }
  7658. +
  7659. + /*
  7660. + * Allocate space for storing data on status transactions. Normally no
  7661. + * data is sent, but this space acts as a bit bucket. This must be
  7662. + * done after usb_add_hcd since that function allocates the DMA buffer
  7663. + * pool.
  7664. + */
  7665. + if (otg_dev->core_if->dma_enable) {
  7666. + dwc_otg_hcd->status_buf =
  7667. + dma_alloc_coherent(_dev,
  7668. + DWC_OTG_HCD_STATUS_BUF_SIZE,
  7669. + &dwc_otg_hcd->status_buf_dma,
  7670. + GFP_KERNEL | GFP_DMA);
  7671. + } else {
  7672. + dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
  7673. + GFP_KERNEL);
  7674. + }
  7675. + if (dwc_otg_hcd->status_buf == NULL) {
  7676. + retval = -ENOMEM;
  7677. + DWC_ERROR("%s: status_buf allocation failed\n", __func__);
  7678. + goto error3;
  7679. + }
  7680. +
  7681. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, bus=%s, usbbus=%d\n",
  7682. + dev_name(_dev), hcd->self.busnum);
  7683. +
  7684. + return 0;
  7685. +
  7686. + /* Error conditions */
  7687. +error3:
  7688. + usb_remove_hcd(hcd);
  7689. +error2:
  7690. + dwc_otg_hcd_free(hcd);
  7691. + usb_put_hcd(hcd);
  7692. +error1:
  7693. + return retval;
  7694. +}
  7695. +
  7696. +/**
  7697. + * Removes the HCD.
  7698. + * Frees memory and resources associated with the HCD and deregisters the bus.
  7699. + */
  7700. +void dwc_otg_hcd_remove(struct device *_dev)
  7701. +{
  7702. + dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);
  7703. + dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd;
  7704. + struct usb_hcd *hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
  7705. +
  7706. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
  7707. +
  7708. + /* Turn off all interrupts */
  7709. + dwc_write_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0);
  7710. + dwc_modify_reg32 (&dwc_otg_hcd->core_if->core_global_regs->gahbcfg, 1, 0);
  7711. +
  7712. + usb_remove_hcd(hcd);
  7713. +
  7714. + dwc_otg_hcd_free(hcd);
  7715. +
  7716. + usb_put_hcd(hcd);
  7717. +
  7718. + return;
  7719. +}
  7720. +
  7721. +
  7722. +/* =========================================================================
  7723. + * Linux HC Driver Functions
  7724. + * ========================================================================= */
  7725. +
  7726. +/**
  7727. + * Initializes dynamic portions of the DWC_otg HCD state.
  7728. + */
  7729. +static void hcd_reinit(dwc_otg_hcd_t *_hcd)
  7730. +{
  7731. + struct list_head *item;
  7732. + int num_channels;
  7733. + int i;
  7734. + dwc_hc_t *channel;
  7735. +
  7736. + _hcd->flags.d32 = 0;
  7737. +
  7738. + _hcd->non_periodic_qh_ptr = &_hcd->non_periodic_sched_active;
  7739. + _hcd->available_host_channels = _hcd->core_if->core_params->host_channels;
  7740. +
  7741. + /*
  7742. + * Put all channels in the free channel list and clean up channel
  7743. + * states.
  7744. + */
  7745. + item = _hcd->free_hc_list.next;
  7746. + while (item != &_hcd->free_hc_list) {
  7747. + list_del(item);
  7748. + item = _hcd->free_hc_list.next;
  7749. + }
  7750. + num_channels = _hcd->core_if->core_params->host_channels;
  7751. + for (i = 0; i < num_channels; i++) {
  7752. + channel = _hcd->hc_ptr_array[i];
  7753. + list_add_tail(&channel->hc_list_entry, &_hcd->free_hc_list);
  7754. + dwc_otg_hc_cleanup(_hcd->core_if, channel);
  7755. + }
  7756. +
  7757. + /* Initialize the DWC core for host mode operation. */
  7758. + dwc_otg_core_host_init(_hcd->core_if);
  7759. +}
  7760. +
  7761. +/** Initializes the DWC_otg controller and its root hub and prepares it for host
  7762. + * mode operation. Activates the root port. Returns 0 on success and a negative
  7763. + * error code on failure. */
  7764. +int dwc_otg_hcd_start(struct usb_hcd *_hcd)
  7765. +{
  7766. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
  7767. + dwc_otg_core_if_t * core_if = dwc_otg_hcd->core_if;
  7768. + struct usb_bus *bus;
  7769. +
  7770. + // int retval;
  7771. +
  7772. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
  7773. +
  7774. + bus = hcd_to_bus(_hcd);
  7775. +
  7776. + /* Initialize the bus state. If the core is in Device Mode
  7777. + * HALT the USB bus and return. */
  7778. + if (dwc_otg_is_device_mode (core_if)) {
  7779. + _hcd->state = HC_STATE_HALT;
  7780. + return 0;
  7781. + }
  7782. + _hcd->state = HC_STATE_RUNNING;
  7783. +
  7784. + /* Initialize and connect root hub if one is not already attached */
  7785. + if (bus->root_hub) {
  7786. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n");
  7787. + /* Inform the HUB driver to resume. */
  7788. + usb_hcd_resume_root_hub(_hcd);
  7789. + }
  7790. + else {
  7791. +#if 0
  7792. + struct usb_device *udev;
  7793. + udev = usb_alloc_dev(NULL, bus, 0);
  7794. + if (!udev) {
  7795. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error udev alloc\n");
  7796. + return -ENODEV;
  7797. + }
  7798. + udev->speed = USB_SPEED_HIGH;
  7799. + /* Not needed - VJ
  7800. + if ((retval = usb_hcd_register_root_hub(udev, _hcd)) != 0) {
  7801. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error registering %d\n", retval);
  7802. + return -ENODEV;
  7803. + }
  7804. + */
  7805. +#else
  7806. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Error udev alloc\n");
  7807. +#endif
  7808. + }
  7809. +
  7810. + hcd_reinit(dwc_otg_hcd);
  7811. +
  7812. + return 0;
  7813. +}
  7814. +
  7815. +static void qh_list_free(dwc_otg_hcd_t *_hcd, struct list_head *_qh_list)
  7816. +{
  7817. + struct list_head *item;
  7818. + dwc_otg_qh_t *qh;
  7819. +
  7820. + if (_qh_list->next == NULL) {
  7821. + /* The list hasn't been initialized yet. */
  7822. + return;
  7823. + }
  7824. +
  7825. + /* Ensure there are no QTDs or URBs left. */
  7826. + kill_urbs_in_qh_list(_hcd, _qh_list);
  7827. +
  7828. + for (item = _qh_list->next; item != _qh_list; item = _qh_list->next) {
  7829. + qh = list_entry(item, dwc_otg_qh_t, qh_list_entry);
  7830. + dwc_otg_hcd_qh_remove_and_free(_hcd, qh);
  7831. + }
  7832. +}
  7833. +
  7834. +/**
  7835. + * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
  7836. + * stopped.
  7837. + */
  7838. +void dwc_otg_hcd_stop(struct usb_hcd *_hcd)
  7839. +{
  7840. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
  7841. + hprt0_data_t hprt0 = { .d32=0 };
  7842. +
  7843. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
  7844. +
  7845. + /* Turn off all host-specific interrupts. */
  7846. + dwc_otg_disable_host_interrupts( dwc_otg_hcd->core_if );
  7847. +
  7848. + /*
  7849. + * The root hub should be disconnected before this function is called.
  7850. + * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
  7851. + * and the QH lists (via ..._hcd_endpoint_disable).
  7852. + */
  7853. +
  7854. + /* Turn off the vbus power */
  7855. + DWC_PRINT("PortPower off\n");
  7856. + hprt0.b.prtpwr = 0;
  7857. + dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32);
  7858. +
  7859. + return;
  7860. +}
  7861. +
  7862. +
  7863. +/** Returns the current frame number. */
  7864. +int dwc_otg_hcd_get_frame_number(struct usb_hcd *_hcd)
  7865. +{
  7866. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
  7867. + hfnum_data_t hfnum;
  7868. +
  7869. + hfnum.d32 = dwc_read_reg32(&dwc_otg_hcd->core_if->
  7870. + host_if->host_global_regs->hfnum);
  7871. +
  7872. +#ifdef DEBUG_SOF
  7873. + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n", hfnum.b.frnum);
  7874. +#endif
  7875. + return hfnum.b.frnum;
  7876. +}
  7877. +
  7878. +/**
  7879. + * Frees secondary storage associated with the dwc_otg_hcd structure contained
  7880. + * in the struct usb_hcd field.
  7881. + */
  7882. +void dwc_otg_hcd_free(struct usb_hcd *_hcd)
  7883. +{
  7884. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
  7885. + int i;
  7886. +
  7887. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n");
  7888. +
  7889. + del_timers(dwc_otg_hcd);
  7890. +
  7891. + /* Free memory for QH/QTD lists */
  7892. + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive);
  7893. + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_deferred);
  7894. + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active);
  7895. + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive);
  7896. + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready);
  7897. + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned);
  7898. + qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued);
  7899. +
  7900. + /* Free memory for the host channels. */
  7901. + for (i = 0; i < MAX_EPS_CHANNELS; i++) {
  7902. + dwc_hc_t *hc = dwc_otg_hcd->hc_ptr_array[i];
  7903. + if (hc != NULL) {
  7904. + DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n", i, hc);
  7905. + kfree(hc);
  7906. + }
  7907. + }
  7908. +
  7909. + if (dwc_otg_hcd->core_if->dma_enable) {
  7910. + if (dwc_otg_hcd->status_buf_dma) {
  7911. + dma_free_coherent(_hcd->self.controller,
  7912. + DWC_OTG_HCD_STATUS_BUF_SIZE,
  7913. + dwc_otg_hcd->status_buf,
  7914. + dwc_otg_hcd->status_buf_dma);
  7915. + }
  7916. + } else if (dwc_otg_hcd->status_buf != NULL) {
  7917. + kfree(dwc_otg_hcd->status_buf);
  7918. + }
  7919. +
  7920. + return;
  7921. +}
  7922. +
  7923. +
  7924. +#ifdef DEBUG
  7925. +static void dump_urb_info(struct urb *_urb, char* _fn_name)
  7926. +{
  7927. + DWC_PRINT("%s, urb %p\n", _fn_name, _urb);
  7928. + DWC_PRINT(" Device address: %d\n", usb_pipedevice(_urb->pipe));
  7929. + DWC_PRINT(" Endpoint: %d, %s\n", usb_pipeendpoint(_urb->pipe),
  7930. + (usb_pipein(_urb->pipe) ? "IN" : "OUT"));
  7931. + DWC_PRINT(" Endpoint type: %s\n",
  7932. + ({char *pipetype;
  7933. + switch (usb_pipetype(_urb->pipe)) {
  7934. + case PIPE_CONTROL: pipetype = "CONTROL"; break;
  7935. + case PIPE_BULK: pipetype = "BULK"; break;
  7936. + case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
  7937. + case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
  7938. + default: pipetype = "UNKNOWN"; break;
  7939. + }; pipetype;}));
  7940. + DWC_PRINT(" Speed: %s\n",
  7941. + ({char *speed;
  7942. + switch (_urb->dev->speed) {
  7943. + case USB_SPEED_HIGH: speed = "HIGH"; break;
  7944. + case USB_SPEED_FULL: speed = "FULL"; break;
  7945. + case USB_SPEED_LOW: speed = "LOW"; break;
  7946. + default: speed = "UNKNOWN"; break;
  7947. + }; speed;}));
  7948. + DWC_PRINT(" Max packet size: %d\n",
  7949. + usb_maxpacket(_urb->dev, _urb->pipe, usb_pipeout(_urb->pipe)));
  7950. + DWC_PRINT(" Data buffer length: %d\n", _urb->transfer_buffer_length);
  7951. + DWC_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n",
  7952. + _urb->transfer_buffer, (void *)_urb->transfer_dma);
  7953. + DWC_PRINT(" Setup buffer: %p, Setup DMA: %p\n",
  7954. + _urb->setup_packet, (void *)_urb->setup_dma);
  7955. + DWC_PRINT(" Interval: %d\n", _urb->interval);
  7956. + if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS) {
  7957. + int i;
  7958. + for (i = 0; i < _urb->number_of_packets; i++) {
  7959. + DWC_PRINT(" ISO Desc %d:\n", i);
  7960. + DWC_PRINT(" offset: %d, length %d\n",
  7961. + _urb->iso_frame_desc[i].offset,
  7962. + _urb->iso_frame_desc[i].length);
  7963. + }
  7964. + }
  7965. +}
  7966. +
  7967. +static void dump_channel_info(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *qh)
  7968. +{
  7969. + if (qh->channel != NULL) {
  7970. + dwc_hc_t *hc = qh->channel;
  7971. + struct list_head *item;
  7972. + dwc_otg_qh_t *qh_item;
  7973. + int num_channels = _hcd->core_if->core_params->host_channels;
  7974. + int i;
  7975. +
  7976. + dwc_otg_hc_regs_t *hc_regs;
  7977. + hcchar_data_t hcchar;
  7978. + hcsplt_data_t hcsplt;
  7979. + hctsiz_data_t hctsiz;
  7980. + uint32_t hcdma;
  7981. +
  7982. + hc_regs = _hcd->core_if->host_if->hc_regs[hc->hc_num];
  7983. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  7984. + hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
  7985. + hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz);
  7986. + hcdma = dwc_read_reg32(&hc_regs->hcdma);
  7987. +
  7988. + DWC_PRINT(" Assigned to channel %p:\n", hc);
  7989. + DWC_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
  7990. + DWC_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
  7991. + DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
  7992. + hc->dev_addr, hc->ep_num, hc->ep_is_in);
  7993. + DWC_PRINT(" ep_type: %d\n", hc->ep_type);
  7994. + DWC_PRINT(" max_packet: %d\n", hc->max_packet);
  7995. + DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
  7996. + DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
  7997. + DWC_PRINT(" halt_status: %d\n", hc->halt_status);
  7998. + DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
  7999. + DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
  8000. + DWC_PRINT(" qh: %p\n", hc->qh);
  8001. + DWC_PRINT(" NP inactive sched:\n");
  8002. + list_for_each(item, &_hcd->non_periodic_sched_inactive) {
  8003. + qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
  8004. + DWC_PRINT(" %p\n", qh_item);
  8005. + } DWC_PRINT(" NP active sched:\n");
  8006. + list_for_each(item, &_hcd->non_periodic_sched_deferred) {
  8007. + qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
  8008. + DWC_PRINT(" %p\n", qh_item);
  8009. + } DWC_PRINT(" NP deferred sched:\n");
  8010. + list_for_each(item, &_hcd->non_periodic_sched_active) {
  8011. + qh_item = list_entry(item, dwc_otg_qh_t, qh_list_entry);
  8012. + DWC_PRINT(" %p\n", qh_item);
  8013. + } DWC_PRINT(" Channels: \n");
  8014. + for (i = 0; i < num_channels; i++) {
  8015. + dwc_hc_t *hc = _hcd->hc_ptr_array[i];
  8016. + DWC_PRINT(" %2d: %p\n", i, hc);
  8017. + }
  8018. + }
  8019. +}
  8020. +#endif // DEBUG
  8021. +
  8022. +/** Starts processing a USB transfer request specified by a USB Request Block
  8023. + * (URB). mem_flags indicates the type of memory allocation to use while
  8024. + * processing this URB. */
  8025. +int dwc_otg_hcd_urb_enqueue(struct usb_hcd *_hcd,
  8026. + struct urb *_urb,
  8027. + gfp_t _mem_flags)
  8028. +{
  8029. + unsigned long flags;
  8030. + int retval;
  8031. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
  8032. + dwc_otg_qtd_t *qtd;
  8033. +
  8034. + local_irq_save(flags);
  8035. + retval = usb_hcd_link_urb_to_ep(_hcd, _urb);
  8036. + if (retval) {
  8037. + local_irq_restore(flags);
  8038. + return retval;
  8039. + }
  8040. +#ifdef DEBUG
  8041. + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
  8042. + dump_urb_info(_urb, "dwc_otg_hcd_urb_enqueue");
  8043. + }
  8044. +#endif // DEBUG
  8045. + if (!dwc_otg_hcd->flags.b.port_connect_status) {
  8046. + /* No longer connected. */
  8047. + local_irq_restore(flags);
  8048. + return -ENODEV;
  8049. + }
  8050. +
  8051. + qtd = dwc_otg_hcd_qtd_create (_urb);
  8052. + if (qtd == NULL) {
  8053. + local_irq_restore(flags);
  8054. + DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n");
  8055. + return -ENOMEM;
  8056. + }
  8057. +
  8058. + retval = dwc_otg_hcd_qtd_add (qtd, dwc_otg_hcd);
  8059. + if (retval < 0) {
  8060. + DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. "
  8061. + "Error status %d\n", retval);
  8062. + dwc_otg_hcd_qtd_free(qtd);
  8063. + }
  8064. +
  8065. + local_irq_restore (flags);
  8066. + return retval;
  8067. +}
  8068. +
  8069. +/** Aborts/cancels a USB transfer request. Always returns 0 to indicate
  8070. + * success. */
  8071. +int dwc_otg_hcd_urb_dequeue(struct usb_hcd *_hcd, struct urb *_urb, int _status)
  8072. +{
  8073. + unsigned long flags;
  8074. + dwc_otg_hcd_t *dwc_otg_hcd;
  8075. + dwc_otg_qtd_t *urb_qtd;
  8076. + dwc_otg_qh_t *qh;
  8077. + int retval;
  8078. + //struct usb_host_endpoint *_ep = NULL;
  8079. +
  8080. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
  8081. +
  8082. + local_irq_save(flags);
  8083. +
  8084. + retval = usb_hcd_check_unlink_urb(_hcd, _urb, _status);
  8085. + if (retval) {
  8086. + local_irq_restore(flags);
  8087. + return retval;
  8088. + }
  8089. +
  8090. + dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
  8091. + urb_qtd = (dwc_otg_qtd_t *)_urb->hcpriv;
  8092. + if (urb_qtd == NULL) {
  8093. + printk("urb_qtd is NULL for _urb %08x\n",(unsigned)_urb);
  8094. + goto done;
  8095. + }
  8096. + qh = (dwc_otg_qh_t *) urb_qtd->qtd_qh_ptr;
  8097. + if (qh == NULL) {
  8098. + goto done;
  8099. + }
  8100. +
  8101. +#ifdef DEBUG
  8102. + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
  8103. + dump_urb_info(_urb, "dwc_otg_hcd_urb_dequeue");
  8104. + if (urb_qtd == qh->qtd_in_process) {
  8105. + dump_channel_info(dwc_otg_hcd, qh);
  8106. + }
  8107. + }
  8108. +#endif // DEBUG
  8109. +
  8110. + if (urb_qtd == qh->qtd_in_process) {
  8111. + /* The QTD is in process (it has been assigned to a channel). */
  8112. +
  8113. + if (dwc_otg_hcd->flags.b.port_connect_status) {
  8114. + /*
  8115. + * If still connected (i.e. in host mode), halt the
  8116. + * channel so it can be used for other transfers. If
  8117. + * no longer connected, the host registers can't be
  8118. + * written to halt the channel since the core is in
  8119. + * device mode.
  8120. + */
  8121. + dwc_otg_hc_halt(dwc_otg_hcd->core_if, qh->channel,
  8122. + DWC_OTG_HC_XFER_URB_DEQUEUE);
  8123. + }
  8124. + }
  8125. +
  8126. + /*
  8127. + * Free the QTD and clean up the associated QH. Leave the QH in the
  8128. + * schedule if it has any remaining QTDs.
  8129. + */
  8130. + dwc_otg_hcd_qtd_remove_and_free(urb_qtd);
  8131. + if (urb_qtd == qh->qtd_in_process) {
  8132. + dwc_otg_hcd_qh_deactivate(dwc_otg_hcd, qh, 0);
  8133. + qh->channel = NULL;
  8134. + qh->qtd_in_process = NULL;
  8135. + } else if (list_empty(&qh->qtd_list)) {
  8136. + dwc_otg_hcd_qh_remove(dwc_otg_hcd, qh);
  8137. + }
  8138. +
  8139. +done:
  8140. + local_irq_restore(flags);
  8141. + _urb->hcpriv = NULL;
  8142. +
  8143. + /* Higher layer software sets URB status. */
  8144. + usb_hcd_unlink_urb_from_ep(_hcd, _urb);
  8145. + usb_hcd_giveback_urb(_hcd, _urb, _status);
  8146. + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
  8147. + DWC_PRINT("Called usb_hcd_giveback_urb()\n");
  8148. + DWC_PRINT(" urb->status = %d\n", _urb->status);
  8149. + }
  8150. +
  8151. + return 0;
  8152. +}
  8153. +
  8154. +
  8155. +/** Frees resources in the DWC_otg controller related to a given endpoint. Also
  8156. + * clears state in the HCD related to the endpoint. Any URBs for the endpoint
  8157. + * must already be dequeued. */
  8158. +void dwc_otg_hcd_endpoint_disable(struct usb_hcd *_hcd,
  8159. + struct usb_host_endpoint *_ep)
  8160. +
  8161. +{
  8162. + dwc_otg_qh_t *qh;
  8163. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd);
  8164. +
  8165. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
  8166. + "endpoint=%d\n", _ep->desc.bEndpointAddress,
  8167. + dwc_ep_addr_to_endpoint(_ep->desc.bEndpointAddress));
  8168. +
  8169. + qh = (dwc_otg_qh_t *)(_ep->hcpriv);
  8170. + if (qh != NULL) {
  8171. +#ifdef DEBUG
  8172. + /** Check that the QTD list is really empty */
  8173. + if (!list_empty(&qh->qtd_list)) {
  8174. + DWC_WARN("DWC OTG HCD EP DISABLE:"
  8175. + " QTD List for this endpoint is not empty\n");
  8176. + }
  8177. +#endif // DEBUG
  8178. +
  8179. + dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh);
  8180. + _ep->hcpriv = NULL;
  8181. + }
  8182. +
  8183. + return;
  8184. +}
  8185. +extern int dwc_irq;
  8186. +/** Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
  8187. + * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
  8188. + * interrupt.
  8189. + *
  8190. + * This function is called by the USB core when an interrupt occurs */
  8191. +irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *_hcd)
  8192. +{
  8193. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
  8194. +
  8195. + mask_and_ack_ifx_irq (dwc_irq);
  8196. + return IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd));
  8197. +}
  8198. +
  8199. +/** Creates Status Change bitmap for the root hub and root port. The bitmap is
  8200. + * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
  8201. + * is the status change indicator for the single root port. Returns 1 if either
  8202. + * change indicator is 1, otherwise returns 0. */
  8203. +int dwc_otg_hcd_hub_status_data(struct usb_hcd *_hcd, char *_buf)
  8204. +{
  8205. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
  8206. +
  8207. + _buf[0] = 0;
  8208. + _buf[0] |= (dwc_otg_hcd->flags.b.port_connect_status_change ||
  8209. + dwc_otg_hcd->flags.b.port_reset_change ||
  8210. + dwc_otg_hcd->flags.b.port_enable_change ||
  8211. + dwc_otg_hcd->flags.b.port_suspend_change ||
  8212. + dwc_otg_hcd->flags.b.port_over_current_change) << 1;
  8213. +
  8214. +#ifdef DEBUG
  8215. + if (_buf[0]) {
  8216. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:"
  8217. + " Root port status changed\n");
  8218. + DWC_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
  8219. + dwc_otg_hcd->flags.b.port_connect_status_change);
  8220. + DWC_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
  8221. + dwc_otg_hcd->flags.b.port_reset_change);
  8222. + DWC_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
  8223. + dwc_otg_hcd->flags.b.port_enable_change);
  8224. + DWC_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
  8225. + dwc_otg_hcd->flags.b.port_suspend_change);
  8226. + DWC_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
  8227. + dwc_otg_hcd->flags.b.port_over_current_change);
  8228. + }
  8229. +#endif // DEBUG
  8230. + return (_buf[0] != 0);
  8231. +}
  8232. +
  8233. +#ifdef DWC_HS_ELECT_TST
  8234. +/*
  8235. + * Quick and dirty hack to implement the HS Electrical Test
  8236. + * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature.
  8237. + *
  8238. + * This code was copied from our userspace app "hset". It sends a
  8239. + * Get Device Descriptor control sequence in two parts, first the
  8240. + * Setup packet by itself, followed some time later by the In and
  8241. + * Ack packets. Rather than trying to figure out how to add this
  8242. + * functionality to the normal driver code, we just hijack the
  8243. + * hardware, using these two function to drive the hardware
  8244. + * directly.
  8245. + */
  8246. +
  8247. +dwc_otg_core_global_regs_t *global_regs;
  8248. +dwc_otg_host_global_regs_t *hc_global_regs;
  8249. +dwc_otg_hc_regs_t *hc_regs;
  8250. +uint32_t *data_fifo;
  8251. +
  8252. +static void do_setup(void)
  8253. +{
  8254. + gintsts_data_t gintsts;
  8255. + hctsiz_data_t hctsiz;
  8256. + hcchar_data_t hcchar;
  8257. + haint_data_t haint;
  8258. + hcint_data_t hcint;
  8259. +
  8260. + /* Enable HAINTs */
  8261. + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
  8262. +
  8263. + /* Enable HCINTs */
  8264. + dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
  8265. +
  8266. + /* Read GINTSTS */
  8267. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8268. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8269. +
  8270. + /* Read HAINT */
  8271. + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
  8272. + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  8273. +
  8274. + /* Read HCINT */
  8275. + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
  8276. + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  8277. +
  8278. + /* Read HCCHAR */
  8279. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8280. + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  8281. +
  8282. + /* Clear HCINT */
  8283. + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
  8284. +
  8285. + /* Clear HAINT */
  8286. + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
  8287. +
  8288. + /* Clear GINTSTS */
  8289. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8290. +
  8291. + /* Read GINTSTS */
  8292. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8293. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8294. +
  8295. + /*
  8296. + * Send Setup packet (Get Device Descriptor)
  8297. + */
  8298. +
  8299. + /* Make sure channel is disabled */
  8300. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8301. + if (hcchar.b.chen) {
  8302. + //fprintf(stderr, "Channel already enabled 1, HCCHAR = %08x\n", hcchar.d32);
  8303. + hcchar.b.chdis = 1;
  8304. + // hcchar.b.chen = 1;
  8305. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  8306. + //sleep(1);
  8307. + MDELAY(1000);
  8308. +
  8309. + /* Read GINTSTS */
  8310. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8311. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8312. +
  8313. + /* Read HAINT */
  8314. + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
  8315. + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  8316. +
  8317. + /* Read HCINT */
  8318. + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
  8319. + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  8320. +
  8321. + /* Read HCCHAR */
  8322. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8323. + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  8324. +
  8325. + /* Clear HCINT */
  8326. + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
  8327. +
  8328. + /* Clear HAINT */
  8329. + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
  8330. +
  8331. + /* Clear GINTSTS */
  8332. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8333. +
  8334. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8335. + //if (hcchar.b.chen) {
  8336. + // fprintf(stderr, "** Channel _still_ enabled 1, HCCHAR = %08x **\n", hcchar.d32);
  8337. + //}
  8338. + }
  8339. +
  8340. + /* Set HCTSIZ */
  8341. + hctsiz.d32 = 0;
  8342. + hctsiz.b.xfersize = 8;
  8343. + hctsiz.b.pktcnt = 1;
  8344. + hctsiz.b.pid = DWC_OTG_HC_PID_SETUP;
  8345. + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
  8346. +
  8347. + /* Set HCCHAR */
  8348. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8349. + hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
  8350. + hcchar.b.epdir = 0;
  8351. + hcchar.b.epnum = 0;
  8352. + hcchar.b.mps = 8;
  8353. + hcchar.b.chen = 1;
  8354. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  8355. +
  8356. + /* Fill FIFO with Setup data for Get Device Descriptor */
  8357. + data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
  8358. + dwc_write_reg32(data_fifo++, 0x01000680);
  8359. + dwc_write_reg32(data_fifo++, 0x00080000);
  8360. +
  8361. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8362. + //fprintf(stderr, "Waiting for HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
  8363. +
  8364. + /* Wait for host channel interrupt */
  8365. + do {
  8366. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8367. + } while (gintsts.b.hcintr == 0);
  8368. +
  8369. + //fprintf(stderr, "Got HCINTR intr 1, GINTSTS = %08x\n", gintsts.d32);
  8370. +
  8371. + /* Disable HCINTs */
  8372. + dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
  8373. +
  8374. + /* Disable HAINTs */
  8375. + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
  8376. +
  8377. + /* Read HAINT */
  8378. + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
  8379. + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  8380. +
  8381. + /* Read HCINT */
  8382. + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
  8383. + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  8384. +
  8385. + /* Read HCCHAR */
  8386. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8387. + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  8388. +
  8389. + /* Clear HCINT */
  8390. + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
  8391. +
  8392. + /* Clear HAINT */
  8393. + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
  8394. +
  8395. + /* Clear GINTSTS */
  8396. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8397. +
  8398. + /* Read GINTSTS */
  8399. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8400. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8401. +}
  8402. +
  8403. +static void do_in_ack(void)
  8404. +{
  8405. + gintsts_data_t gintsts;
  8406. + hctsiz_data_t hctsiz;
  8407. + hcchar_data_t hcchar;
  8408. + haint_data_t haint;
  8409. + hcint_data_t hcint;
  8410. + host_grxsts_data_t grxsts;
  8411. +
  8412. + /* Enable HAINTs */
  8413. + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001);
  8414. +
  8415. + /* Enable HCINTs */
  8416. + dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3);
  8417. +
  8418. + /* Read GINTSTS */
  8419. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8420. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8421. +
  8422. + /* Read HAINT */
  8423. + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
  8424. + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  8425. +
  8426. + /* Read HCINT */
  8427. + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
  8428. + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  8429. +
  8430. + /* Read HCCHAR */
  8431. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8432. + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  8433. +
  8434. + /* Clear HCINT */
  8435. + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
  8436. +
  8437. + /* Clear HAINT */
  8438. + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
  8439. +
  8440. + /* Clear GINTSTS */
  8441. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8442. +
  8443. + /* Read GINTSTS */
  8444. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8445. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8446. +
  8447. + /*
  8448. + * Receive Control In packet
  8449. + */
  8450. +
  8451. + /* Make sure channel is disabled */
  8452. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8453. + if (hcchar.b.chen) {
  8454. + //fprintf(stderr, "Channel already enabled 2, HCCHAR = %08x\n", hcchar.d32);
  8455. + hcchar.b.chdis = 1;
  8456. + hcchar.b.chen = 1;
  8457. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  8458. + //sleep(1);
  8459. + MDELAY(1000);
  8460. +
  8461. + /* Read GINTSTS */
  8462. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8463. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8464. +
  8465. + /* Read HAINT */
  8466. + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
  8467. + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  8468. +
  8469. + /* Read HCINT */
  8470. + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
  8471. + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  8472. +
  8473. + /* Read HCCHAR */
  8474. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8475. + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  8476. +
  8477. + /* Clear HCINT */
  8478. + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
  8479. +
  8480. + /* Clear HAINT */
  8481. + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
  8482. +
  8483. + /* Clear GINTSTS */
  8484. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8485. +
  8486. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8487. + //if (hcchar.b.chen) {
  8488. + // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32);
  8489. + //}
  8490. + }
  8491. +
  8492. + /* Set HCTSIZ */
  8493. + hctsiz.d32 = 0;
  8494. + hctsiz.b.xfersize = 8;
  8495. + hctsiz.b.pktcnt = 1;
  8496. + hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
  8497. + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
  8498. +
  8499. + /* Set HCCHAR */
  8500. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8501. + hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
  8502. + hcchar.b.epdir = 1;
  8503. + hcchar.b.epnum = 0;
  8504. + hcchar.b.mps = 8;
  8505. + hcchar.b.chen = 1;
  8506. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  8507. +
  8508. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8509. + //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
  8510. +
  8511. + /* Wait for receive status queue interrupt */
  8512. + do {
  8513. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8514. + } while (gintsts.b.rxstsqlvl == 0);
  8515. +
  8516. + //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32);
  8517. +
  8518. + /* Read RXSTS */
  8519. + grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
  8520. + //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
  8521. +
  8522. + /* Clear RXSTSQLVL in GINTSTS */
  8523. + gintsts.d32 = 0;
  8524. + gintsts.b.rxstsqlvl = 1;
  8525. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8526. +
  8527. + switch (grxsts.b.pktsts) {
  8528. + case DWC_GRXSTS_PKTSTS_IN:
  8529. + /* Read the data into the host buffer */
  8530. + if (grxsts.b.bcnt > 0) {
  8531. + int i;
  8532. + int word_count = (grxsts.b.bcnt + 3) / 4;
  8533. +
  8534. + data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
  8535. +
  8536. + for (i = 0; i < word_count; i++) {
  8537. + (void)dwc_read_reg32(data_fifo++);
  8538. + }
  8539. + }
  8540. +
  8541. + //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.b.bcnt);
  8542. + break;
  8543. +
  8544. + default:
  8545. + //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n");
  8546. + break;
  8547. + }
  8548. +
  8549. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8550. + //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
  8551. +
  8552. + /* Wait for receive status queue interrupt */
  8553. + do {
  8554. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8555. + } while (gintsts.b.rxstsqlvl == 0);
  8556. +
  8557. + //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32);
  8558. +
  8559. + /* Read RXSTS */
  8560. + grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp);
  8561. + //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32);
  8562. +
  8563. + /* Clear RXSTSQLVL in GINTSTS */
  8564. + gintsts.d32 = 0;
  8565. + gintsts.b.rxstsqlvl = 1;
  8566. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8567. +
  8568. + switch (grxsts.b.pktsts) {
  8569. + case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
  8570. + break;
  8571. +
  8572. + default:
  8573. + //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n");
  8574. + break;
  8575. + }
  8576. +
  8577. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8578. + //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
  8579. +
  8580. + /* Wait for host channel interrupt */
  8581. + do {
  8582. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8583. + } while (gintsts.b.hcintr == 0);
  8584. +
  8585. + //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32);
  8586. +
  8587. + /* Read HAINT */
  8588. + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
  8589. + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  8590. +
  8591. + /* Read HCINT */
  8592. + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
  8593. + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  8594. +
  8595. + /* Read HCCHAR */
  8596. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8597. + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  8598. +
  8599. + /* Clear HCINT */
  8600. + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
  8601. +
  8602. + /* Clear HAINT */
  8603. + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
  8604. +
  8605. + /* Clear GINTSTS */
  8606. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8607. +
  8608. + /* Read GINTSTS */
  8609. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8610. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8611. +
  8612. + // usleep(100000);
  8613. + // mdelay(100);
  8614. + MDELAY(1);
  8615. +
  8616. + /*
  8617. + * Send handshake packet
  8618. + */
  8619. +
  8620. + /* Read HAINT */
  8621. + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
  8622. + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  8623. +
  8624. + /* Read HCINT */
  8625. + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
  8626. + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  8627. +
  8628. + /* Read HCCHAR */
  8629. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8630. + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  8631. +
  8632. + /* Clear HCINT */
  8633. + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
  8634. +
  8635. + /* Clear HAINT */
  8636. + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
  8637. +
  8638. + /* Clear GINTSTS */
  8639. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8640. +
  8641. + /* Read GINTSTS */
  8642. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8643. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8644. +
  8645. + /* Make sure channel is disabled */
  8646. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8647. + if (hcchar.b.chen) {
  8648. + //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32);
  8649. + hcchar.b.chdis = 1;
  8650. + hcchar.b.chen = 1;
  8651. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  8652. + //sleep(1);
  8653. + MDELAY(1000);
  8654. +
  8655. + /* Read GINTSTS */
  8656. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8657. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8658. +
  8659. + /* Read HAINT */
  8660. + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
  8661. + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  8662. +
  8663. + /* Read HCINT */
  8664. + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
  8665. + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  8666. +
  8667. + /* Read HCCHAR */
  8668. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8669. + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  8670. +
  8671. + /* Clear HCINT */
  8672. + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
  8673. +
  8674. + /* Clear HAINT */
  8675. + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
  8676. +
  8677. + /* Clear GINTSTS */
  8678. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8679. +
  8680. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8681. + //if (hcchar.b.chen) {
  8682. + // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32);
  8683. + //}
  8684. + }
  8685. +
  8686. + /* Set HCTSIZ */
  8687. + hctsiz.d32 = 0;
  8688. + hctsiz.b.xfersize = 0;
  8689. + hctsiz.b.pktcnt = 1;
  8690. + hctsiz.b.pid = DWC_OTG_HC_PID_DATA1;
  8691. + dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
  8692. +
  8693. + /* Set HCCHAR */
  8694. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8695. + hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL;
  8696. + hcchar.b.epdir = 0;
  8697. + hcchar.b.epnum = 0;
  8698. + hcchar.b.mps = 8;
  8699. + hcchar.b.chen = 1;
  8700. + dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
  8701. +
  8702. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8703. + //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
  8704. +
  8705. + /* Wait for host channel interrupt */
  8706. + do {
  8707. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8708. + } while (gintsts.b.hcintr == 0);
  8709. +
  8710. + //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32);
  8711. +
  8712. + /* Disable HCINTs */
  8713. + dwc_write_reg32(&hc_regs->hcintmsk, 0x0000);
  8714. +
  8715. + /* Disable HAINTs */
  8716. + dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000);
  8717. +
  8718. + /* Read HAINT */
  8719. + haint.d32 = dwc_read_reg32(&hc_global_regs->haint);
  8720. + //fprintf(stderr, "HAINT: %08x\n", haint.d32);
  8721. +
  8722. + /* Read HCINT */
  8723. + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
  8724. + //fprintf(stderr, "HCINT: %08x\n", hcint.d32);
  8725. +
  8726. + /* Read HCCHAR */
  8727. + hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
  8728. + //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32);
  8729. +
  8730. + /* Clear HCINT */
  8731. + dwc_write_reg32(&hc_regs->hcint, hcint.d32);
  8732. +
  8733. + /* Clear HAINT */
  8734. + dwc_write_reg32(&hc_global_regs->haint, haint.d32);
  8735. +
  8736. + /* Clear GINTSTS */
  8737. + dwc_write_reg32(&global_regs->gintsts, gintsts.d32);
  8738. +
  8739. + /* Read GINTSTS */
  8740. + gintsts.d32 = dwc_read_reg32(&global_regs->gintsts);
  8741. + //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);
  8742. +}
  8743. +#endif /* DWC_HS_ELECT_TST */
  8744. +
  8745. +/** Handles hub class-specific requests.*/
  8746. +int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd,
  8747. + u16 _typeReq,
  8748. + u16 _wValue,
  8749. + u16 _wIndex,
  8750. + char *_buf,
  8751. + u16 _wLength)
  8752. +{
  8753. + int retval = 0;
  8754. +
  8755. + dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (_hcd);
  8756. + dwc_otg_core_if_t *core_if = hcd_to_dwc_otg_hcd (_hcd)->core_if;
  8757. + struct usb_hub_descriptor *desc;
  8758. + hprt0_data_t hprt0 = {.d32 = 0};
  8759. +
  8760. + uint32_t port_status;
  8761. +
  8762. + switch (_typeReq) {
  8763. + case ClearHubFeature:
  8764. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8765. + "ClearHubFeature 0x%x\n", _wValue);
  8766. + switch (_wValue) {
  8767. + case C_HUB_LOCAL_POWER:
  8768. + case C_HUB_OVER_CURRENT:
  8769. + /* Nothing required here */
  8770. + break;
  8771. + default:
  8772. + retval = -EINVAL;
  8773. + DWC_ERROR ("DWC OTG HCD - "
  8774. + "ClearHubFeature request %xh unknown\n", _wValue);
  8775. + }
  8776. + break;
  8777. + case ClearPortFeature:
  8778. + if (!_wIndex || _wIndex > 1)
  8779. + goto error;
  8780. +
  8781. + switch (_wValue) {
  8782. + case USB_PORT_FEAT_ENABLE:
  8783. + DWC_DEBUGPL (DBG_ANY, "DWC OTG HCD HUB CONTROL - "
  8784. + "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
  8785. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  8786. + hprt0.b.prtena = 1;
  8787. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  8788. + break;
  8789. + case USB_PORT_FEAT_SUSPEND:
  8790. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8791. + "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
  8792. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  8793. + hprt0.b.prtres = 1;
  8794. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  8795. + /* Clear Resume bit */
  8796. + mdelay (100);
  8797. + hprt0.b.prtres = 0;
  8798. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  8799. + break;
  8800. + case USB_PORT_FEAT_POWER:
  8801. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8802. + "ClearPortFeature USB_PORT_FEAT_POWER\n");
  8803. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  8804. + hprt0.b.prtpwr = 0;
  8805. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  8806. + break;
  8807. + case USB_PORT_FEAT_INDICATOR:
  8808. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8809. + "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
  8810. + /* Port inidicator not supported */
  8811. + break;
  8812. + case USB_PORT_FEAT_C_CONNECTION:
  8813. + /* Clears drivers internal connect status change
  8814. + * flag */
  8815. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8816. + "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
  8817. + dwc_otg_hcd->flags.b.port_connect_status_change = 0;
  8818. + break;
  8819. + case USB_PORT_FEAT_C_RESET:
  8820. + /* Clears the driver's internal Port Reset Change
  8821. + * flag */
  8822. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8823. + "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
  8824. + dwc_otg_hcd->flags.b.port_reset_change = 0;
  8825. + break;
  8826. + case USB_PORT_FEAT_C_ENABLE:
  8827. + /* Clears the driver's internal Port
  8828. + * Enable/Disable Change flag */
  8829. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8830. + "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
  8831. + dwc_otg_hcd->flags.b.port_enable_change = 0;
  8832. + break;
  8833. + case USB_PORT_FEAT_C_SUSPEND:
  8834. + /* Clears the driver's internal Port Suspend
  8835. + * Change flag, which is set when resume signaling on
  8836. + * the host port is complete */
  8837. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8838. + "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
  8839. + dwc_otg_hcd->flags.b.port_suspend_change = 0;
  8840. + break;
  8841. + case USB_PORT_FEAT_C_OVER_CURRENT:
  8842. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8843. + "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
  8844. + dwc_otg_hcd->flags.b.port_over_current_change = 0;
  8845. + break;
  8846. + default:
  8847. + retval = -EINVAL;
  8848. + DWC_ERROR ("DWC OTG HCD - "
  8849. + "ClearPortFeature request %xh "
  8850. + "unknown or unsupported\n", _wValue);
  8851. + }
  8852. + break;
  8853. + case GetHubDescriptor:
  8854. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8855. + "GetHubDescriptor\n");
  8856. + desc = (struct usb_hub_descriptor *)_buf;
  8857. + desc->bDescLength = 9;
  8858. + desc->bDescriptorType = 0x29;
  8859. + desc->bNbrPorts = 1;
  8860. + desc->wHubCharacteristics = 0x08;
  8861. + desc->bPwrOn2PwrGood = 1;
  8862. + desc->bHubContrCurrent = 0;
  8863. + desc->u.hs.DeviceRemovable[0] = 0;
  8864. + desc->u.hs.DeviceRemovable[1] = 0xff;
  8865. + break;
  8866. + case GetHubStatus:
  8867. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8868. + "GetHubStatus\n");
  8869. + memset (_buf, 0, 4);
  8870. + break;
  8871. + case GetPortStatus:
  8872. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8873. + "GetPortStatus\n");
  8874. +
  8875. + if (!_wIndex || _wIndex > 1)
  8876. + goto error;
  8877. +
  8878. + port_status = 0;
  8879. +
  8880. + if (dwc_otg_hcd->flags.b.port_connect_status_change)
  8881. + port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
  8882. +
  8883. + if (dwc_otg_hcd->flags.b.port_enable_change)
  8884. + port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
  8885. +
  8886. + if (dwc_otg_hcd->flags.b.port_suspend_change)
  8887. + port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
  8888. +
  8889. + if (dwc_otg_hcd->flags.b.port_reset_change)
  8890. + port_status |= (1 << USB_PORT_FEAT_C_RESET);
  8891. +
  8892. + if (dwc_otg_hcd->flags.b.port_over_current_change) {
  8893. + DWC_ERROR("Device Not Supported\n");
  8894. + port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
  8895. + }
  8896. +
  8897. + if (!dwc_otg_hcd->flags.b.port_connect_status) {
  8898. + printk("DISCONNECTED PORT\n");
  8899. + /*
  8900. + * The port is disconnected, which means the core is
  8901. + * either in device mode or it soon will be. Just
  8902. + * return 0's for the remainder of the port status
  8903. + * since the port register can't be read if the core
  8904. + * is in device mode.
  8905. + */
  8906. +#if 1 // winder.
  8907. + *((u32 *) _buf) = cpu_to_le32(port_status);
  8908. +#else
  8909. + *((__le32 *) _buf) = cpu_to_le32(port_status);
  8910. +#endif
  8911. + break;
  8912. + }
  8913. +
  8914. + hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
  8915. + DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
  8916. +
  8917. + if (hprt0.b.prtconnsts)
  8918. + port_status |= (1 << USB_PORT_FEAT_CONNECTION);
  8919. +
  8920. + if (hprt0.b.prtena)
  8921. + port_status |= (1 << USB_PORT_FEAT_ENABLE);
  8922. +
  8923. + if (hprt0.b.prtsusp)
  8924. + port_status |= (1 << USB_PORT_FEAT_SUSPEND);
  8925. +
  8926. + if (hprt0.b.prtovrcurract)
  8927. + port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
  8928. +
  8929. + if (hprt0.b.prtrst)
  8930. + port_status |= (1 << USB_PORT_FEAT_RESET);
  8931. +
  8932. + if (hprt0.b.prtpwr)
  8933. + port_status |= (1 << USB_PORT_FEAT_POWER);
  8934. +
  8935. + if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
  8936. + port_status |= USB_PORT_STAT_HIGH_SPEED;
  8937. +
  8938. + else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
  8939. + port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
  8940. +
  8941. + if (hprt0.b.prttstctl)
  8942. + port_status |= (1 << USB_PORT_FEAT_TEST);
  8943. +
  8944. + /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
  8945. +#if 1 // winder.
  8946. + *((u32 *) _buf) = cpu_to_le32(port_status);
  8947. +#else
  8948. + *((__le32 *) _buf) = cpu_to_le32(port_status);
  8949. +#endif
  8950. +
  8951. + break;
  8952. + case SetHubFeature:
  8953. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8954. + "SetHubFeature\n");
  8955. + /* No HUB features supported */
  8956. + break;
  8957. + case SetPortFeature:
  8958. + if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
  8959. + goto error;
  8960. +
  8961. + if (!dwc_otg_hcd->flags.b.port_connect_status) {
  8962. + /*
  8963. + * The port is disconnected, which means the core is
  8964. + * either in device mode or it soon will be. Just
  8965. + * return without doing anything since the port
  8966. + * register can't be written if the core is in device
  8967. + * mode.
  8968. + */
  8969. + break;
  8970. + }
  8971. +
  8972. + switch (_wValue) {
  8973. + case USB_PORT_FEAT_SUSPEND:
  8974. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  8975. + "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
  8976. + if (_hcd->self.otg_port == _wIndex
  8977. + && _hcd->self.b_hnp_enable) {
  8978. + gotgctl_data_t gotgctl = {.d32=0};
  8979. + gotgctl.b.hstsethnpen = 1;
  8980. + dwc_modify_reg32(&core_if->core_global_regs->
  8981. + gotgctl, 0, gotgctl.d32);
  8982. + core_if->op_state = A_SUSPEND;
  8983. + }
  8984. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  8985. + hprt0.b.prtsusp = 1;
  8986. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  8987. + //DWC_PRINT( "SUSPEND: HPRT0=%0x\n", hprt0.d32);
  8988. + /* Suspend the Phy Clock */
  8989. + {
  8990. + pcgcctl_data_t pcgcctl = {.d32=0};
  8991. + pcgcctl.b.stoppclk = 1;
  8992. + dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
  8993. + }
  8994. +
  8995. + /* For HNP the bus must be suspended for at least 200ms.*/
  8996. + if (_hcd->self.b_hnp_enable) {
  8997. + mdelay(200);
  8998. + //DWC_PRINT( "SUSPEND: wait complete! (%d)\n", _hcd->state);
  8999. + }
  9000. + break;
  9001. + case USB_PORT_FEAT_POWER:
  9002. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  9003. + "SetPortFeature - USB_PORT_FEAT_POWER\n");
  9004. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  9005. + hprt0.b.prtpwr = 1;
  9006. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  9007. + break;
  9008. + case USB_PORT_FEAT_RESET:
  9009. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  9010. + "SetPortFeature - USB_PORT_FEAT_RESET\n");
  9011. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  9012. + /* TODO: Is this for OTG protocol??
  9013. + * We shoudl remove OTG totally for Danube system.
  9014. + * But, in the future, maybe we need this.
  9015. + */
  9016. +#if 1 // winder
  9017. + hprt0.b.prtrst = 1;
  9018. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  9019. +#else
  9020. + /* When B-Host the Port reset bit is set in
  9021. + * the Start HCD Callback function, so that
  9022. + * the reset is started within 1ms of the HNP
  9023. + * success interrupt. */
  9024. + if (!_hcd->self.is_b_host) {
  9025. + hprt0.b.prtrst = 1;
  9026. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  9027. + }
  9028. +#endif
  9029. + /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
  9030. + MDELAY (60);
  9031. + hprt0.b.prtrst = 0;
  9032. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  9033. + break;
  9034. +
  9035. +#ifdef DWC_HS_ELECT_TST
  9036. + case USB_PORT_FEAT_TEST:
  9037. + {
  9038. + uint32_t t;
  9039. + gintmsk_data_t gintmsk;
  9040. +
  9041. + t = (_wIndex >> 8); /* MSB wIndex USB */
  9042. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  9043. + "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
  9044. + printk("USB_PORT_FEAT_TEST %d\n", t);
  9045. + if (t < 6) {
  9046. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  9047. + hprt0.b.prttstctl = t;
  9048. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  9049. + } else {
  9050. + /* Setup global vars with reg addresses (quick and
  9051. + * dirty hack, should be cleaned up)
  9052. + */
  9053. + global_regs = core_if->core_global_regs;
  9054. + hc_global_regs = core_if->host_if->host_global_regs;
  9055. + hc_regs = (dwc_otg_hc_regs_t *)((char *)global_regs + 0x500);
  9056. + data_fifo = (uint32_t *)((char *)global_regs + 0x1000);
  9057. +
  9058. + if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */
  9059. + /* Save current interrupt mask */
  9060. + gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
  9061. +
  9062. + /* Disable all interrupts while we muck with
  9063. + * the hardware directly
  9064. + */
  9065. + dwc_write_reg32(&global_regs->gintmsk, 0);
  9066. +
  9067. + /* 15 second delay per the test spec */
  9068. + mdelay(15000);
  9069. +
  9070. + /* Drive suspend on the root port */
  9071. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  9072. + hprt0.b.prtsusp = 1;
  9073. + hprt0.b.prtres = 0;
  9074. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  9075. +
  9076. + /* 15 second delay per the test spec */
  9077. + mdelay(15000);
  9078. +
  9079. + /* Drive resume on the root port */
  9080. + hprt0.d32 = dwc_otg_read_hprt0 (core_if);
  9081. + hprt0.b.prtsusp = 0;
  9082. + hprt0.b.prtres = 1;
  9083. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  9084. + mdelay(100);
  9085. +
  9086. + /* Clear the resume bit */
  9087. + hprt0.b.prtres = 0;
  9088. + dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
  9089. +
  9090. + /* Restore interrupts */
  9091. + dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
  9092. + } else if (t == 7) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
  9093. + /* Save current interrupt mask */
  9094. + gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
  9095. +
  9096. + /* Disable all interrupts while we muck with
  9097. + * the hardware directly
  9098. + */
  9099. + dwc_write_reg32(&global_regs->gintmsk, 0);
  9100. +
  9101. + /* 15 second delay per the test spec */
  9102. + mdelay(15000);
  9103. +
  9104. + /* Send the Setup packet */
  9105. + do_setup();
  9106. +
  9107. + /* 15 second delay so nothing else happens for awhile */
  9108. + mdelay(15000);
  9109. +
  9110. + /* Restore interrupts */
  9111. + dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
  9112. + } else if (t == 8) { /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
  9113. + /* Save current interrupt mask */
  9114. + gintmsk.d32 = dwc_read_reg32(&global_regs->gintmsk);
  9115. +
  9116. + /* Disable all interrupts while we muck with
  9117. + * the hardware directly
  9118. + */
  9119. + dwc_write_reg32(&global_regs->gintmsk, 0);
  9120. +
  9121. + /* Send the Setup packet */
  9122. + do_setup();
  9123. +
  9124. + /* 15 second delay so nothing else happens for awhile */
  9125. + mdelay(15000);
  9126. +
  9127. + /* Send the In and Ack packets */
  9128. + do_in_ack();
  9129. +
  9130. + /* 15 second delay so nothing else happens for awhile */
  9131. + mdelay(15000);
  9132. +
  9133. + /* Restore interrupts */
  9134. + dwc_write_reg32(&global_regs->gintmsk, gintmsk.d32);
  9135. + }
  9136. + }
  9137. + break;
  9138. + }
  9139. +#endif /* DWC_HS_ELECT_TST */
  9140. +
  9141. + case USB_PORT_FEAT_INDICATOR:
  9142. + DWC_DEBUGPL (DBG_HCD, "DWC OTG HCD HUB CONTROL - "
  9143. + "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
  9144. + /* Not supported */
  9145. + break;
  9146. + default:
  9147. + retval = -EINVAL;
  9148. + DWC_ERROR ("DWC OTG HCD - "
  9149. + "SetPortFeature request %xh "
  9150. + "unknown or unsupported\n", _wValue);
  9151. + break;
  9152. + }
  9153. + break;
  9154. + default:
  9155. +error:
  9156. + retval = -EINVAL;
  9157. + DWC_WARN ("DWC OTG HCD - "
  9158. + "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
  9159. + _typeReq, _wIndex, _wValue);
  9160. + break;
  9161. + }
  9162. +
  9163. + return retval;
  9164. +}
  9165. +
  9166. +
  9167. +/**
  9168. + * Assigns transactions from a QTD to a free host channel and initializes the
  9169. + * host channel to perform the transactions. The host channel is removed from
  9170. + * the free list.
  9171. + *
  9172. + * @param _hcd The HCD state structure.
  9173. + * @param _qh Transactions from the first QTD for this QH are selected and
  9174. + * assigned to a free host channel.
  9175. + */
  9176. +static void assign_and_init_hc(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
  9177. +{
  9178. + dwc_hc_t *hc;
  9179. + dwc_otg_qtd_t *qtd;
  9180. + struct urb *urb;
  9181. +
  9182. + DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, _hcd, _qh);
  9183. +
  9184. + hc = list_entry(_hcd->free_hc_list.next, dwc_hc_t, hc_list_entry);
  9185. +
  9186. + /* Remove the host channel from the free list. */
  9187. + list_del_init(&hc->hc_list_entry);
  9188. +
  9189. + qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
  9190. + urb = qtd->urb;
  9191. + _qh->channel = hc;
  9192. + _qh->qtd_in_process = qtd;
  9193. +
  9194. + /*
  9195. + * Use usb_pipedevice to determine device address. This address is
  9196. + * 0 before the SET_ADDRESS command and the correct address afterward.
  9197. + */
  9198. + hc->dev_addr = usb_pipedevice(urb->pipe);
  9199. + hc->ep_num = usb_pipeendpoint(urb->pipe);
  9200. +
  9201. + if (urb->dev->speed == USB_SPEED_LOW) {
  9202. + hc->speed = DWC_OTG_EP_SPEED_LOW;
  9203. + } else if (urb->dev->speed == USB_SPEED_FULL) {
  9204. + hc->speed = DWC_OTG_EP_SPEED_FULL;
  9205. + } else {
  9206. + hc->speed = DWC_OTG_EP_SPEED_HIGH;
  9207. + }
  9208. + hc->max_packet = dwc_max_packet(_qh->maxp);
  9209. +
  9210. + hc->xfer_started = 0;
  9211. + hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
  9212. + hc->error_state = (qtd->error_count > 0);
  9213. + hc->halt_on_queue = 0;
  9214. + hc->halt_pending = 0;
  9215. + hc->requests = 0;
  9216. +
  9217. + /*
  9218. + * The following values may be modified in the transfer type section
  9219. + * below. The xfer_len value may be reduced when the transfer is
  9220. + * started to accommodate the max widths of the XferSize and PktCnt
  9221. + * fields in the HCTSIZn register.
  9222. + */
  9223. + hc->do_ping = _qh->ping_state;
  9224. + hc->ep_is_in = (usb_pipein(urb->pipe) != 0);
  9225. + hc->data_pid_start = _qh->data_toggle;
  9226. + hc->multi_count = 1;
  9227. +
  9228. + if (_hcd->core_if->dma_enable) {
  9229. + hc->xfer_buff = (uint8_t *)(u32)urb->transfer_dma + urb->actual_length;
  9230. + } else {
  9231. + hc->xfer_buff = (uint8_t *)urb->transfer_buffer + urb->actual_length;
  9232. + }
  9233. + hc->xfer_len = urb->transfer_buffer_length - urb->actual_length;
  9234. + hc->xfer_count = 0;
  9235. +
  9236. + /*
  9237. + * Set the split attributes
  9238. + */
  9239. + hc->do_split = 0;
  9240. + if (_qh->do_split) {
  9241. + hc->do_split = 1;
  9242. + hc->xact_pos = qtd->isoc_split_pos;
  9243. + hc->complete_split = qtd->complete_split;
  9244. + hc->hub_addr = urb->dev->tt->hub->devnum;
  9245. + hc->port_addr = urb->dev->ttport;
  9246. + }
  9247. +
  9248. + switch (usb_pipetype(urb->pipe)) {
  9249. + case PIPE_CONTROL:
  9250. + hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
  9251. + switch (qtd->control_phase) {
  9252. + case DWC_OTG_CONTROL_SETUP:
  9253. + DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n");
  9254. + hc->do_ping = 0;
  9255. + hc->ep_is_in = 0;
  9256. + hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
  9257. + if (_hcd->core_if->dma_enable) {
  9258. + hc->xfer_buff = (uint8_t *)(u32)urb->setup_dma;
  9259. + } else {
  9260. + hc->xfer_buff = (uint8_t *)urb->setup_packet;
  9261. + }
  9262. + hc->xfer_len = 8;
  9263. + break;
  9264. + case DWC_OTG_CONTROL_DATA:
  9265. + DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
  9266. + hc->data_pid_start = qtd->data_toggle;
  9267. + break;
  9268. + case DWC_OTG_CONTROL_STATUS:
  9269. + /*
  9270. + * Direction is opposite of data direction or IN if no
  9271. + * data.
  9272. + */
  9273. + DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n");
  9274. + if (urb->transfer_buffer_length == 0) {
  9275. + hc->ep_is_in = 1;
  9276. + } else {
  9277. + hc->ep_is_in = (usb_pipein(urb->pipe) != USB_DIR_IN);
  9278. + }
  9279. + if (hc->ep_is_in) {
  9280. + hc->do_ping = 0;
  9281. + }
  9282. + hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
  9283. + hc->xfer_len = 0;
  9284. + if (_hcd->core_if->dma_enable) {
  9285. + hc->xfer_buff = (uint8_t *)_hcd->status_buf_dma;
  9286. + } else {
  9287. + hc->xfer_buff = (uint8_t *)_hcd->status_buf;
  9288. + }
  9289. + break;
  9290. + }
  9291. + break;
  9292. + case PIPE_BULK:
  9293. + hc->ep_type = DWC_OTG_EP_TYPE_BULK;
  9294. + break;
  9295. + case PIPE_INTERRUPT:
  9296. + hc->ep_type = DWC_OTG_EP_TYPE_INTR;
  9297. + break;
  9298. + case PIPE_ISOCHRONOUS:
  9299. + {
  9300. + struct usb_iso_packet_descriptor *frame_desc;
  9301. + frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index];
  9302. + hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
  9303. + if (_hcd->core_if->dma_enable) {
  9304. + hc->xfer_buff = (uint8_t *)(u32)urb->transfer_dma;
  9305. + } else {
  9306. + hc->xfer_buff = (uint8_t *)urb->transfer_buffer;
  9307. + }
  9308. + hc->xfer_buff += frame_desc->offset + qtd->isoc_split_offset;
  9309. + hc->xfer_len = frame_desc->length - qtd->isoc_split_offset;
  9310. +
  9311. + if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
  9312. + if (hc->xfer_len <= 188) {
  9313. + hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
  9314. + }
  9315. + else {
  9316. + hc->xact_pos = DWC_HCSPLIT_XACTPOS_BEGIN;
  9317. + }
  9318. + }
  9319. + }
  9320. + break;
  9321. + }
  9322. +
  9323. + if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
  9324. + hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
  9325. + /*
  9326. + * This value may be modified when the transfer is started to
  9327. + * reflect the actual transfer length.
  9328. + */
  9329. + hc->multi_count = dwc_hb_mult(_qh->maxp);
  9330. + }
  9331. +
  9332. + dwc_otg_hc_init(_hcd->core_if, hc);
  9333. + hc->qh = _qh;
  9334. +}
  9335. +#define DEBUG_HOST_CHANNELS
  9336. +#ifdef DEBUG_HOST_CHANNELS
  9337. +static int last_sel_trans_num_per_scheduled = 0;
  9338. +module_param(last_sel_trans_num_per_scheduled, int, 0444);
  9339. +
  9340. +static int last_sel_trans_num_nonper_scheduled = 0;
  9341. +module_param(last_sel_trans_num_nonper_scheduled, int, 0444);
  9342. +
  9343. +static int last_sel_trans_num_avail_hc_at_start = 0;
  9344. +module_param(last_sel_trans_num_avail_hc_at_start, int, 0444);
  9345. +
  9346. +static int last_sel_trans_num_avail_hc_at_end = 0;
  9347. +module_param(last_sel_trans_num_avail_hc_at_end, int, 0444);
  9348. +#endif /* DEBUG_HOST_CHANNELS */
  9349. +
  9350. +/**
  9351. + * This function selects transactions from the HCD transfer schedule and
  9352. + * assigns them to available host channels. It is called from HCD interrupt
  9353. + * handler functions.
  9354. + *
  9355. + * @param _hcd The HCD state structure.
  9356. + *
  9357. + * @return The types of new transactions that were assigned to host channels.
  9358. + */
  9359. +dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *_hcd)
  9360. +{
  9361. + struct list_head *qh_ptr;
  9362. + dwc_otg_qh_t *qh;
  9363. + int num_channels;
  9364. + unsigned long flags;
  9365. + dwc_otg_transaction_type_e ret_val = DWC_OTG_TRANSACTION_NONE;
  9366. +
  9367. +#ifdef DEBUG_SOF
  9368. + DWC_DEBUGPL(DBG_HCD, " Select Transactions\n");
  9369. +#endif /* */
  9370. +
  9371. +#ifdef DEBUG_HOST_CHANNELS
  9372. + last_sel_trans_num_per_scheduled = 0;
  9373. + last_sel_trans_num_nonper_scheduled = 0;
  9374. + last_sel_trans_num_avail_hc_at_start = _hcd->available_host_channels;
  9375. +#endif /* DEBUG_HOST_CHANNELS */
  9376. +
  9377. + /* Process entries in the periodic ready list. */
  9378. + num_channels = _hcd->core_if->core_params->host_channels;
  9379. + qh_ptr = _hcd->periodic_sched_ready.next;
  9380. + while (qh_ptr != &_hcd->periodic_sched_ready
  9381. + && !list_empty(&_hcd->free_hc_list)) {
  9382. +
  9383. + // Make sure we leave one channel for non periodic transactions.
  9384. + local_irq_save(flags);
  9385. + if (_hcd->available_host_channels <= 1) {
  9386. + local_irq_restore(flags);
  9387. + break;
  9388. + }
  9389. + _hcd->available_host_channels--;
  9390. + local_irq_restore(flags);
  9391. +#ifdef DEBUG_HOST_CHANNELS
  9392. + last_sel_trans_num_per_scheduled++;
  9393. +#endif /* DEBUG_HOST_CHANNELS */
  9394. +
  9395. + qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
  9396. + assign_and_init_hc(_hcd, qh);
  9397. +
  9398. + /*
  9399. + * Move the QH from the periodic ready schedule to the
  9400. + * periodic assigned schedule.
  9401. + */
  9402. + qh_ptr = qh_ptr->next;
  9403. + local_irq_save(flags);
  9404. + list_move(&qh->qh_list_entry, &_hcd->periodic_sched_assigned);
  9405. + local_irq_restore(flags);
  9406. + ret_val = DWC_OTG_TRANSACTION_PERIODIC;
  9407. + }
  9408. +
  9409. + /*
  9410. + * Process entries in the deferred portion of the non-periodic list.
  9411. + * A NAK put them here and, at the right time, they need to be
  9412. + * placed on the sched_inactive list.
  9413. + */
  9414. + qh_ptr = _hcd->non_periodic_sched_deferred.next;
  9415. + while (qh_ptr != &_hcd->non_periodic_sched_deferred) {
  9416. + uint16_t frame_number =
  9417. + dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(_hcd));
  9418. + qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
  9419. + qh_ptr = qh_ptr->next;
  9420. +
  9421. + if (dwc_frame_num_le(qh->sched_frame, frame_number)) {
  9422. + // NAK did this
  9423. + /*
  9424. + * Move the QH from the non periodic deferred schedule to
  9425. + * the non periodic inactive schedule.
  9426. + */
  9427. + local_irq_save(flags);
  9428. + list_move(&qh->qh_list_entry,
  9429. + &_hcd->non_periodic_sched_inactive);
  9430. + local_irq_restore(flags);
  9431. + }
  9432. + }
  9433. +
  9434. + /*
  9435. + * Process entries in the inactive portion of the non-periodic
  9436. + * schedule. Some free host channels may not be used if they are
  9437. + * reserved for periodic transfers.
  9438. + */
  9439. + qh_ptr = _hcd->non_periodic_sched_inactive.next;
  9440. + num_channels = _hcd->core_if->core_params->host_channels;
  9441. + while (qh_ptr != &_hcd->non_periodic_sched_inactive
  9442. + && !list_empty(&_hcd->free_hc_list)) {
  9443. +
  9444. + local_irq_save(flags);
  9445. + if (_hcd->available_host_channels < 1) {
  9446. + local_irq_restore(flags);
  9447. + break;
  9448. + }
  9449. + _hcd->available_host_channels--;
  9450. + local_irq_restore(flags);
  9451. +#ifdef DEBUG_HOST_CHANNELS
  9452. + last_sel_trans_num_nonper_scheduled++;
  9453. +#endif /* DEBUG_HOST_CHANNELS */
  9454. +
  9455. + qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
  9456. + assign_and_init_hc(_hcd, qh);
  9457. +
  9458. + /*
  9459. + * Move the QH from the non-periodic inactive schedule to the
  9460. + * non-periodic active schedule.
  9461. + */
  9462. + qh_ptr = qh_ptr->next;
  9463. + local_irq_save(flags);
  9464. + list_move(&qh->qh_list_entry, &_hcd->non_periodic_sched_active);
  9465. + local_irq_restore(flags);
  9466. +
  9467. + if (ret_val == DWC_OTG_TRANSACTION_NONE) {
  9468. + ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
  9469. + } else {
  9470. + ret_val = DWC_OTG_TRANSACTION_ALL;
  9471. + }
  9472. +
  9473. + }
  9474. +#ifdef DEBUG_HOST_CHANNELS
  9475. + last_sel_trans_num_avail_hc_at_end = _hcd->available_host_channels;
  9476. +#endif /* DEBUG_HOST_CHANNELS */
  9477. +
  9478. + return ret_val;
  9479. +}
  9480. +
  9481. +/**
  9482. + * Attempts to queue a single transaction request for a host channel
  9483. + * associated with either a periodic or non-periodic transfer. This function
  9484. + * assumes that there is space available in the appropriate request queue. For
  9485. + * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
  9486. + * is available in the appropriate Tx FIFO.
  9487. + *
  9488. + * @param _hcd The HCD state structure.
  9489. + * @param _hc Host channel descriptor associated with either a periodic or
  9490. + * non-periodic transfer.
  9491. + * @param _fifo_dwords_avail Number of DWORDs available in the periodic Tx
  9492. + * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic
  9493. + * transfers.
  9494. + *
  9495. + * @return 1 if a request is queued and more requests may be needed to
  9496. + * complete the transfer, 0 if no more requests are required for this
  9497. + * transfer, -1 if there is insufficient space in the Tx FIFO.
  9498. + */
  9499. +static int queue_transaction(dwc_otg_hcd_t *_hcd,
  9500. + dwc_hc_t *_hc,
  9501. + uint16_t _fifo_dwords_avail)
  9502. +{
  9503. + int retval;
  9504. +
  9505. + if (_hcd->core_if->dma_enable) {
  9506. + if (!_hc->xfer_started) {
  9507. + dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
  9508. + _hc->qh->ping_state = 0;
  9509. + }
  9510. + retval = 0;
  9511. + } else if (_hc->halt_pending) {
  9512. + /* Don't queue a request if the channel has been halted. */
  9513. + retval = 0;
  9514. + } else if (_hc->halt_on_queue) {
  9515. + dwc_otg_hc_halt(_hcd->core_if, _hc, _hc->halt_status);
  9516. + retval = 0;
  9517. + } else if (_hc->do_ping) {
  9518. + if (!_hc->xfer_started) {
  9519. + dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
  9520. + }
  9521. + retval = 0;
  9522. + } else if (!_hc->ep_is_in ||
  9523. + _hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
  9524. + if ((_fifo_dwords_avail * 4) >= _hc->max_packet) {
  9525. + if (!_hc->xfer_started) {
  9526. + dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
  9527. + retval = 1;
  9528. + } else {
  9529. + retval = dwc_otg_hc_continue_transfer(_hcd->core_if, _hc);
  9530. + }
  9531. + } else {
  9532. + retval = -1;
  9533. + }
  9534. + } else {
  9535. + if (!_hc->xfer_started) {
  9536. + dwc_otg_hc_start_transfer(_hcd->core_if, _hc);
  9537. + retval = 1;
  9538. + } else {
  9539. + retval = dwc_otg_hc_continue_transfer(_hcd->core_if, _hc);
  9540. + }
  9541. + }
  9542. +
  9543. + return retval;
  9544. +}
  9545. +
  9546. +/**
  9547. + * Processes active non-periodic channels and queues transactions for these
  9548. + * channels to the DWC_otg controller. After queueing transactions, the NP Tx
  9549. + * FIFO Empty interrupt is enabled if there are more transactions to queue as
  9550. + * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
  9551. + * FIFO Empty interrupt is disabled.
  9552. + */
  9553. +static void process_non_periodic_channels(dwc_otg_hcd_t *_hcd)
  9554. +{
  9555. + gnptxsts_data_t tx_status;
  9556. + struct list_head *orig_qh_ptr;
  9557. + dwc_otg_qh_t *qh;
  9558. + int status;
  9559. + int no_queue_space = 0;
  9560. + int no_fifo_space = 0;
  9561. + int more_to_do = 0;
  9562. +
  9563. + dwc_otg_core_global_regs_t *global_regs = _hcd->core_if->core_global_regs;
  9564. +
  9565. + DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n");
  9566. +#ifdef DEBUG
  9567. + tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
  9568. + DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (before queue): %d\n",
  9569. + tx_status.b.nptxqspcavail);
  9570. + DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n",
  9571. + tx_status.b.nptxfspcavail);
  9572. +#endif
  9573. + /*
  9574. + * Keep track of the starting point. Skip over the start-of-list
  9575. + * entry.
  9576. + */
  9577. + if (_hcd->non_periodic_qh_ptr == &_hcd->non_periodic_sched_active) {
  9578. + _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
  9579. + }
  9580. + orig_qh_ptr = _hcd->non_periodic_qh_ptr;
  9581. +
  9582. + /*
  9583. + * Process once through the active list or until no more space is
  9584. + * available in the request queue or the Tx FIFO.
  9585. + */
  9586. + do {
  9587. + tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
  9588. + if (!_hcd->core_if->dma_enable && tx_status.b.nptxqspcavail == 0) {
  9589. + no_queue_space = 1;
  9590. + break;
  9591. + }
  9592. +
  9593. + qh = list_entry(_hcd->non_periodic_qh_ptr, dwc_otg_qh_t, qh_list_entry);
  9594. + status = queue_transaction(_hcd, qh->channel, tx_status.b.nptxfspcavail);
  9595. +
  9596. + if (status > 0) {
  9597. + more_to_do = 1;
  9598. + } else if (status < 0) {
  9599. + no_fifo_space = 1;
  9600. + break;
  9601. + }
  9602. +
  9603. + /* Advance to next QH, skipping start-of-list entry. */
  9604. + _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
  9605. + if (_hcd->non_periodic_qh_ptr == &_hcd->non_periodic_sched_active) {
  9606. + _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
  9607. + }
  9608. +
  9609. + } while (_hcd->non_periodic_qh_ptr != orig_qh_ptr);
  9610. +
  9611. + if (!_hcd->core_if->dma_enable) {
  9612. + gintmsk_data_t intr_mask = {.d32 = 0};
  9613. + intr_mask.b.nptxfempty = 1;
  9614. +
  9615. +#ifdef DEBUG
  9616. + tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts);
  9617. + DWC_DEBUGPL(DBG_HCDV, " NP Tx Req Queue Space Avail (after queue): %d\n",
  9618. + tx_status.b.nptxqspcavail);
  9619. + DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (after queue): %d\n",
  9620. + tx_status.b.nptxfspcavail);
  9621. +#endif
  9622. + if (more_to_do || no_queue_space || no_fifo_space) {
  9623. + /*
  9624. + * May need to queue more transactions as the request
  9625. + * queue or Tx FIFO empties. Enable the non-periodic
  9626. + * Tx FIFO empty interrupt. (Always use the half-empty
  9627. + * level to ensure that new requests are loaded as
  9628. + * soon as possible.)
  9629. + */
  9630. + dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
  9631. + } else {
  9632. + /*
  9633. + * Disable the Tx FIFO empty interrupt since there are
  9634. + * no more transactions that need to be queued right
  9635. + * now. This function is called from interrupt
  9636. + * handlers to queue more transactions as transfer
  9637. + * states change.
  9638. + */
  9639. + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
  9640. + }
  9641. + }
  9642. +}
  9643. +
  9644. +/**
  9645. + * Processes periodic channels for the next frame and queues transactions for
  9646. + * these channels to the DWC_otg controller. After queueing transactions, the
  9647. + * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
  9648. + * to queue as Periodic Tx FIFO or request queue space becomes available.
  9649. + * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
  9650. + */
  9651. +static void process_periodic_channels(dwc_otg_hcd_t *_hcd)
  9652. +{
  9653. + hptxsts_data_t tx_status;
  9654. + struct list_head *qh_ptr;
  9655. + dwc_otg_qh_t *qh;
  9656. + int status;
  9657. + int no_queue_space = 0;
  9658. + int no_fifo_space = 0;
  9659. +
  9660. + dwc_otg_host_global_regs_t *host_regs;
  9661. + host_regs = _hcd->core_if->host_if->host_global_regs;
  9662. +
  9663. + DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n");
  9664. +#ifdef DEBUG
  9665. + tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
  9666. + DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (before queue): %d\n",
  9667. + tx_status.b.ptxqspcavail);
  9668. + DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n",
  9669. + tx_status.b.ptxfspcavail);
  9670. +#endif
  9671. +
  9672. + qh_ptr = _hcd->periodic_sched_assigned.next;
  9673. + while (qh_ptr != &_hcd->periodic_sched_assigned) {
  9674. + tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
  9675. + if (tx_status.b.ptxqspcavail == 0) {
  9676. + no_queue_space = 1;
  9677. + break;
  9678. + }
  9679. +
  9680. + qh = list_entry(qh_ptr, dwc_otg_qh_t, qh_list_entry);
  9681. +
  9682. + /*
  9683. + * Set a flag if we're queuing high-bandwidth in slave mode.
  9684. + * The flag prevents any halts to get into the request queue in
  9685. + * the middle of multiple high-bandwidth packets getting queued.
  9686. + */
  9687. + if ((!_hcd->core_if->dma_enable) &&
  9688. + (qh->channel->multi_count > 1))
  9689. + {
  9690. + _hcd->core_if->queuing_high_bandwidth = 1;
  9691. + }
  9692. +
  9693. + status = queue_transaction(_hcd, qh->channel, tx_status.b.ptxfspcavail);
  9694. + if (status < 0) {
  9695. + no_fifo_space = 1;
  9696. + break;
  9697. + }
  9698. +
  9699. + /*
  9700. + * In Slave mode, stay on the current transfer until there is
  9701. + * nothing more to do or the high-bandwidth request count is
  9702. + * reached. In DMA mode, only need to queue one request. The
  9703. + * controller automatically handles multiple packets for
  9704. + * high-bandwidth transfers.
  9705. + */
  9706. + if (_hcd->core_if->dma_enable ||
  9707. + (status == 0 ||
  9708. + qh->channel->requests == qh->channel->multi_count)) {
  9709. + qh_ptr = qh_ptr->next;
  9710. + /*
  9711. + * Move the QH from the periodic assigned schedule to
  9712. + * the periodic queued schedule.
  9713. + */
  9714. + list_move(&qh->qh_list_entry, &_hcd->periodic_sched_queued);
  9715. +
  9716. + /* done queuing high bandwidth */
  9717. + _hcd->core_if->queuing_high_bandwidth = 0;
  9718. + }
  9719. + }
  9720. +
  9721. + if (!_hcd->core_if->dma_enable) {
  9722. + dwc_otg_core_global_regs_t *global_regs;
  9723. + gintmsk_data_t intr_mask = {.d32 = 0};
  9724. +
  9725. + global_regs = _hcd->core_if->core_global_regs;
  9726. + intr_mask.b.ptxfempty = 1;
  9727. +#ifdef DEBUG
  9728. + tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
  9729. + DWC_DEBUGPL(DBG_HCDV, " P Tx Req Queue Space Avail (after queue): %d\n",
  9730. + tx_status.b.ptxqspcavail);
  9731. + DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (after queue): %d\n",
  9732. + tx_status.b.ptxfspcavail);
  9733. +#endif
  9734. + if (!(list_empty(&_hcd->periodic_sched_assigned)) ||
  9735. + no_queue_space || no_fifo_space) {
  9736. + /*
  9737. + * May need to queue more transactions as the request
  9738. + * queue or Tx FIFO empties. Enable the periodic Tx
  9739. + * FIFO empty interrupt. (Always use the half-empty
  9740. + * level to ensure that new requests are loaded as
  9741. + * soon as possible.)
  9742. + */
  9743. + dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32);
  9744. + } else {
  9745. + /*
  9746. + * Disable the Tx FIFO empty interrupt since there are
  9747. + * no more transactions that need to be queued right
  9748. + * now. This function is called from interrupt
  9749. + * handlers to queue more transactions as transfer
  9750. + * states change.
  9751. + */
  9752. + dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
  9753. + }
  9754. + }
  9755. +}
  9756. +
  9757. +/**
  9758. + * This function processes the currently active host channels and queues
  9759. + * transactions for these channels to the DWC_otg controller. It is called
  9760. + * from HCD interrupt handler functions.
  9761. + *
  9762. + * @param _hcd The HCD state structure.
  9763. + * @param _tr_type The type(s) of transactions to queue (non-periodic,
  9764. + * periodic, or both).
  9765. + */
  9766. +void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *_hcd,
  9767. + dwc_otg_transaction_type_e _tr_type)
  9768. +{
  9769. +#ifdef DEBUG_SOF
  9770. + DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n");
  9771. +#endif
  9772. + /* Process host channels associated with periodic transfers. */
  9773. + if ((_tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
  9774. + _tr_type == DWC_OTG_TRANSACTION_ALL) &&
  9775. + !list_empty(&_hcd->periodic_sched_assigned)) {
  9776. +
  9777. + process_periodic_channels(_hcd);
  9778. + }
  9779. +
  9780. + /* Process host channels associated with non-periodic transfers. */
  9781. + if ((_tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
  9782. + _tr_type == DWC_OTG_TRANSACTION_ALL)) {
  9783. + if (!list_empty(&_hcd->non_periodic_sched_active)) {
  9784. + process_non_periodic_channels(_hcd);
  9785. + } else {
  9786. + /*
  9787. + * Ensure NP Tx FIFO empty interrupt is disabled when
  9788. + * there are no non-periodic transfers to process.
  9789. + */
  9790. + gintmsk_data_t gintmsk = {.d32 = 0};
  9791. + gintmsk.b.nptxfempty = 1;
  9792. + dwc_modify_reg32(&_hcd->core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
  9793. + }
  9794. + }
  9795. +}
  9796. +
  9797. +/**
  9798. + * Sets the final status of an URB and returns it to the device driver. Any
  9799. + * required cleanup of the URB is performed.
  9800. + */
  9801. +void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t * _hcd, struct urb *_urb,
  9802. + int _status)
  9803. + __releases(_hcd->lock)
  9804. +__acquires(_hcd->lock)
  9805. +{
  9806. +#ifdef DEBUG
  9807. + if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
  9808. + DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n",
  9809. + __func__, _urb, usb_pipedevice(_urb->pipe),
  9810. + usb_pipeendpoint(_urb->pipe),
  9811. + usb_pipein(_urb->pipe) ? "IN" : "OUT", _status);
  9812. + if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS) {
  9813. + int i;
  9814. + for (i = 0; i < _urb->number_of_packets; i++) {
  9815. + DWC_PRINT(" ISO Desc %d status: %d\n",
  9816. + i, _urb->iso_frame_desc[i].status);
  9817. + }
  9818. + }
  9819. + }
  9820. +#endif
  9821. +
  9822. + _urb->status = _status;
  9823. + _urb->hcpriv = NULL;
  9824. + usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(_hcd), _urb);
  9825. + spin_unlock(&_hcd->lock);
  9826. + usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(_hcd), _urb, _status);
  9827. + spin_lock(&_hcd->lock);
  9828. +}
  9829. +
  9830. +/*
  9831. + * Returns the Queue Head for an URB.
  9832. + */
  9833. +dwc_otg_qh_t *dwc_urb_to_qh(struct urb *_urb)
  9834. +{
  9835. + struct usb_host_endpoint *ep = dwc_urb_to_endpoint(_urb);
  9836. + return (dwc_otg_qh_t *)ep->hcpriv;
  9837. +}
  9838. +
  9839. +#ifdef DEBUG
  9840. +void dwc_print_setup_data (uint8_t *setup)
  9841. +{
  9842. + int i;
  9843. + if (CHK_DEBUG_LEVEL(DBG_HCD)){
  9844. + DWC_PRINT("Setup Data = MSB ");
  9845. + for (i=7; i>=0; i--) DWC_PRINT ("%02x ", setup[i]);
  9846. + DWC_PRINT("\n");
  9847. + DWC_PRINT(" bmRequestType Tranfer = %s\n", (setup[0]&0x80) ? "Device-to-Host" : "Host-to-Device");
  9848. + DWC_PRINT(" bmRequestType Type = ");
  9849. + switch ((setup[0]&0x60) >> 5) {
  9850. + case 0: DWC_PRINT("Standard\n"); break;
  9851. + case 1: DWC_PRINT("Class\n"); break;
  9852. + case 2: DWC_PRINT("Vendor\n"); break;
  9853. + case 3: DWC_PRINT("Reserved\n"); break;
  9854. + }
  9855. + DWC_PRINT(" bmRequestType Recipient = ");
  9856. + switch (setup[0]&0x1f) {
  9857. + case 0: DWC_PRINT("Device\n"); break;
  9858. + case 1: DWC_PRINT("Interface\n"); break;
  9859. + case 2: DWC_PRINT("Endpoint\n"); break;
  9860. + case 3: DWC_PRINT("Other\n"); break;
  9861. + default: DWC_PRINT("Reserved\n"); break;
  9862. + }
  9863. + DWC_PRINT(" bRequest = 0x%0x\n", setup[1]);
  9864. + DWC_PRINT(" wValue = 0x%0x\n", *((uint16_t *)&setup[2]));
  9865. + DWC_PRINT(" wIndex = 0x%0x\n", *((uint16_t *)&setup[4]));
  9866. + DWC_PRINT(" wLength = 0x%0x\n\n", *((uint16_t *)&setup[6]));
  9867. + }
  9868. +}
  9869. +#endif
  9870. +
  9871. +void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *_hcd) {
  9872. +#ifdef DEBUG
  9873. +#if 0
  9874. + DWC_PRINT("Frame remaining at SOF:\n");
  9875. + DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
  9876. + _hcd->frrem_samples, _hcd->frrem_accum,
  9877. + (_hcd->frrem_samples > 0) ?
  9878. + _hcd->frrem_accum/_hcd->frrem_samples : 0);
  9879. +
  9880. + DWC_PRINT("\n");
  9881. + DWC_PRINT("Frame remaining at start_transfer (uframe 7):\n");
  9882. + DWC_PRINT(" samples %u, accum %u, avg %u\n",
  9883. + _hcd->core_if->hfnum_7_samples, _hcd->core_if->hfnum_7_frrem_accum,
  9884. + (_hcd->core_if->hfnum_7_samples > 0) ?
  9885. + _hcd->core_if->hfnum_7_frrem_accum/_hcd->core_if->hfnum_7_samples : 0);
  9886. + DWC_PRINT("Frame remaining at start_transfer (uframe 0):\n");
  9887. + DWC_PRINT(" samples %u, accum %u, avg %u\n",
  9888. + _hcd->core_if->hfnum_0_samples, _hcd->core_if->hfnum_0_frrem_accum,
  9889. + (_hcd->core_if->hfnum_0_samples > 0) ?
  9890. + _hcd->core_if->hfnum_0_frrem_accum/_hcd->core_if->hfnum_0_samples : 0);
  9891. + DWC_PRINT("Frame remaining at start_transfer (uframe 1-6):\n");
  9892. + DWC_PRINT(" samples %u, accum %u, avg %u\n",
  9893. + _hcd->core_if->hfnum_other_samples, _hcd->core_if->hfnum_other_frrem_accum,
  9894. + (_hcd->core_if->hfnum_other_samples > 0) ?
  9895. + _hcd->core_if->hfnum_other_frrem_accum/_hcd->core_if->hfnum_other_samples : 0);
  9896. +
  9897. + DWC_PRINT("\n");
  9898. + DWC_PRINT("Frame remaining at sample point A (uframe 7):\n");
  9899. + DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
  9900. + _hcd->hfnum_7_samples_a, _hcd->hfnum_7_frrem_accum_a,
  9901. + (_hcd->hfnum_7_samples_a > 0) ?
  9902. + _hcd->hfnum_7_frrem_accum_a/_hcd->hfnum_7_samples_a : 0);
  9903. + DWC_PRINT("Frame remaining at sample point A (uframe 0):\n");
  9904. + DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
  9905. + _hcd->hfnum_0_samples_a, _hcd->hfnum_0_frrem_accum_a,
  9906. + (_hcd->hfnum_0_samples_a > 0) ?
  9907. + _hcd->hfnum_0_frrem_accum_a/_hcd->hfnum_0_samples_a : 0);
  9908. + DWC_PRINT("Frame remaining at sample point A (uframe 1-6):\n");
  9909. + DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
  9910. + _hcd->hfnum_other_samples_a, _hcd->hfnum_other_frrem_accum_a,
  9911. + (_hcd->hfnum_other_samples_a > 0) ?
  9912. + _hcd->hfnum_other_frrem_accum_a/_hcd->hfnum_other_samples_a : 0);
  9913. +
  9914. + DWC_PRINT("\n");
  9915. + DWC_PRINT("Frame remaining at sample point B (uframe 7):\n");
  9916. + DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
  9917. + _hcd->hfnum_7_samples_b, _hcd->hfnum_7_frrem_accum_b,
  9918. + (_hcd->hfnum_7_samples_b > 0) ?
  9919. + _hcd->hfnum_7_frrem_accum_b/_hcd->hfnum_7_samples_b : 0);
  9920. + DWC_PRINT("Frame remaining at sample point B (uframe 0):\n");
  9921. + DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
  9922. + _hcd->hfnum_0_samples_b, _hcd->hfnum_0_frrem_accum_b,
  9923. + (_hcd->hfnum_0_samples_b > 0) ?
  9924. + _hcd->hfnum_0_frrem_accum_b/_hcd->hfnum_0_samples_b : 0);
  9925. + DWC_PRINT("Frame remaining at sample point B (uframe 1-6):\n");
  9926. + DWC_PRINT(" samples %u, accum %llu, avg %llu\n",
  9927. + _hcd->hfnum_other_samples_b, _hcd->hfnum_other_frrem_accum_b,
  9928. + (_hcd->hfnum_other_samples_b > 0) ?
  9929. + _hcd->hfnum_other_frrem_accum_b/_hcd->hfnum_other_samples_b : 0);
  9930. +#endif
  9931. +#endif
  9932. +}
  9933. +
  9934. +void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *_hcd)
  9935. +{
  9936. +#ifdef DEBUG
  9937. + int num_channels;
  9938. + int i;
  9939. + gnptxsts_data_t np_tx_status;
  9940. + hptxsts_data_t p_tx_status;
  9941. +
  9942. + num_channels = _hcd->core_if->core_params->host_channels;
  9943. + DWC_PRINT("\n");
  9944. + DWC_PRINT("************************************************************\n");
  9945. + DWC_PRINT("HCD State:\n");
  9946. + DWC_PRINT(" Num channels: %d\n", num_channels);
  9947. + for (i = 0; i < num_channels; i++) {
  9948. + dwc_hc_t *hc = _hcd->hc_ptr_array[i];
  9949. + DWC_PRINT(" Channel %d:\n", i);
  9950. + DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
  9951. + hc->dev_addr, hc->ep_num, hc->ep_is_in);
  9952. + DWC_PRINT(" speed: %d\n", hc->speed);
  9953. + DWC_PRINT(" ep_type: %d\n", hc->ep_type);
  9954. + DWC_PRINT(" max_packet: %d\n", hc->max_packet);
  9955. + DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start);
  9956. + DWC_PRINT(" multi_count: %d\n", hc->multi_count);
  9957. + DWC_PRINT(" xfer_started: %d\n", hc->xfer_started);
  9958. + DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff);
  9959. + DWC_PRINT(" xfer_len: %d\n", hc->xfer_len);
  9960. + DWC_PRINT(" xfer_count: %d\n", hc->xfer_count);
  9961. + DWC_PRINT(" halt_on_queue: %d\n", hc->halt_on_queue);
  9962. + DWC_PRINT(" halt_pending: %d\n", hc->halt_pending);
  9963. + DWC_PRINT(" halt_status: %d\n", hc->halt_status);
  9964. + DWC_PRINT(" do_split: %d\n", hc->do_split);
  9965. + DWC_PRINT(" complete_split: %d\n", hc->complete_split);
  9966. + DWC_PRINT(" hub_addr: %d\n", hc->hub_addr);
  9967. + DWC_PRINT(" port_addr: %d\n", hc->port_addr);
  9968. + DWC_PRINT(" xact_pos: %d\n", hc->xact_pos);
  9969. + DWC_PRINT(" requests: %d\n", hc->requests);
  9970. + DWC_PRINT(" qh: %p\n", hc->qh);
  9971. + if (hc->xfer_started) {
  9972. + hfnum_data_t hfnum;
  9973. + hcchar_data_t hcchar;
  9974. + hctsiz_data_t hctsiz;
  9975. + hcint_data_t hcint;
  9976. + hcintmsk_data_t hcintmsk;
  9977. + hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum);
  9978. + hcchar.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hcchar);
  9979. + hctsiz.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hctsiz);
  9980. + hcint.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hcint);
  9981. + hcintmsk.d32 = dwc_read_reg32(&_hcd->core_if->host_if->hc_regs[i]->hcintmsk);
  9982. + DWC_PRINT(" hfnum: 0x%08x\n", hfnum.d32);
  9983. + DWC_PRINT(" hcchar: 0x%08x\n", hcchar.d32);
  9984. + DWC_PRINT(" hctsiz: 0x%08x\n", hctsiz.d32);
  9985. + DWC_PRINT(" hcint: 0x%08x\n", hcint.d32);
  9986. + DWC_PRINT(" hcintmsk: 0x%08x\n", hcintmsk.d32);
  9987. + }
  9988. + if (hc->xfer_started && (hc->qh != NULL) && (hc->qh->qtd_in_process != NULL)) {
  9989. + dwc_otg_qtd_t *qtd;
  9990. + struct urb *urb;
  9991. + qtd = hc->qh->qtd_in_process;
  9992. + urb = qtd->urb;
  9993. + DWC_PRINT(" URB Info:\n");
  9994. + DWC_PRINT(" qtd: %p, urb: %p\n", qtd, urb);
  9995. + if (urb != NULL) {
  9996. + DWC_PRINT(" Dev: %d, EP: %d %s\n",
  9997. + usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe),
  9998. + usb_pipein(urb->pipe) ? "IN" : "OUT");
  9999. + DWC_PRINT(" Max packet size: %d\n",
  10000. + usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
  10001. + DWC_PRINT(" transfer_buffer: %p\n", urb->transfer_buffer);
  10002. + DWC_PRINT(" transfer_dma: %p\n", (void *)urb->transfer_dma);
  10003. + DWC_PRINT(" transfer_buffer_length: %d\n", urb->transfer_buffer_length);
  10004. + DWC_PRINT(" actual_length: %d\n", urb->actual_length);
  10005. + }
  10006. + }
  10007. + }
  10008. + //DWC_PRINT(" non_periodic_channels: %d\n", _hcd->non_periodic_channels);
  10009. + //DWC_PRINT(" periodic_channels: %d\n", _hcd->periodic_channels);
  10010. + DWC_PRINT(" available_channels: %d\n", _hcd->available_host_channels);
  10011. + DWC_PRINT(" periodic_usecs: %d\n", _hcd->periodic_usecs);
  10012. + np_tx_status.d32 = dwc_read_reg32(&_hcd->core_if->core_global_regs->gnptxsts);
  10013. + DWC_PRINT(" NP Tx Req Queue Space Avail: %d\n", np_tx_status.b.nptxqspcavail);
  10014. + DWC_PRINT(" NP Tx FIFO Space Avail: %d\n", np_tx_status.b.nptxfspcavail);
  10015. + p_tx_status.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hptxsts);
  10016. + DWC_PRINT(" P Tx Req Queue Space Avail: %d\n", p_tx_status.b.ptxqspcavail);
  10017. + DWC_PRINT(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail);
  10018. + dwc_otg_hcd_dump_frrem(_hcd);
  10019. + dwc_otg_dump_global_registers(_hcd->core_if);
  10020. + dwc_otg_dump_host_registers(_hcd->core_if);
  10021. + DWC_PRINT("************************************************************\n");
  10022. + DWC_PRINT("\n");
  10023. +#endif
  10024. +}
  10025. +#endif /* DWC_DEVICE_ONLY */
  10026. diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.h b/drivers/usb/dwc_otg/dwc_otg_hcd.h
  10027. new file mode 100644
  10028. index 0000000..8a20dff
  10029. --- /dev/null
  10030. +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.h
  10031. @@ -0,0 +1,676 @@
  10032. +/* ==========================================================================
  10033. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd.h $
  10034. + * $Revision: 1.1.1.1 $
  10035. + * $Date: 2009-04-17 06:15:34 $
  10036. + * $Change: 537387 $
  10037. + *
  10038. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  10039. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  10040. + * otherwise expressly agreed to in writing between Synopsys and you.
  10041. + *
  10042. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  10043. + * any End User Software License Agreement or Agreement for Licensed Product
  10044. + * with Synopsys or any supplement thereto. You are permitted to use and
  10045. + * redistribute this Software in source and binary forms, with or without
  10046. + * modification, provided that redistributions of source code must retain this
  10047. + * notice. You may not view, use, disclose, copy or distribute this file or
  10048. + * any information contained herein except pursuant to this license grant from
  10049. + * Synopsys. If you do not agree with this notice, including the disclaimer
  10050. + * below, then you are not authorized to use the Software.
  10051. + *
  10052. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  10053. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  10054. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  10055. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  10056. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  10057. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  10058. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  10059. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  10060. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  10061. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  10062. + * DAMAGE.
  10063. + * ========================================================================== */
  10064. +#ifndef DWC_DEVICE_ONLY
  10065. +#if !defined(__DWC_HCD_H__)
  10066. +#define __DWC_HCD_H__
  10067. +
  10068. +#include <linux/list.h>
  10069. +#include <linux/usb.h>
  10070. +#include <linux/usb/hcd.h>
  10071. +
  10072. +struct lm_device;
  10073. +struct dwc_otg_device;
  10074. +
  10075. +#include "dwc_otg_cil.h"
  10076. +//#include "dwc_otg_ifx.h" // winder
  10077. +
  10078. +
  10079. +/**
  10080. + * @file
  10081. + *
  10082. + * This file contains the structures, constants, and interfaces for
  10083. + * the Host Contoller Driver (HCD).
  10084. + *
  10085. + * The Host Controller Driver (HCD) is responsible for translating requests
  10086. + * from the USB Driver into the appropriate actions on the DWC_otg controller.
  10087. + * It isolates the USBD from the specifics of the controller by providing an
  10088. + * API to the USBD.
  10089. + */
  10090. +
  10091. +/**
  10092. + * Phases for control transfers.
  10093. + */
  10094. +typedef enum dwc_otg_control_phase {
  10095. + DWC_OTG_CONTROL_SETUP,
  10096. + DWC_OTG_CONTROL_DATA,
  10097. + DWC_OTG_CONTROL_STATUS
  10098. +} dwc_otg_control_phase_e;
  10099. +
  10100. +/** Transaction types. */
  10101. +typedef enum dwc_otg_transaction_type {
  10102. + DWC_OTG_TRANSACTION_NONE,
  10103. + DWC_OTG_TRANSACTION_PERIODIC,
  10104. + DWC_OTG_TRANSACTION_NON_PERIODIC,
  10105. + DWC_OTG_TRANSACTION_ALL
  10106. +} dwc_otg_transaction_type_e;
  10107. +
  10108. +/**
  10109. + * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control,
  10110. + * interrupt, or isochronous transfer. A single QTD is created for each URB
  10111. + * (of one of these types) submitted to the HCD. The transfer associated with
  10112. + * a QTD may require one or multiple transactions.
  10113. + *
  10114. + * A QTD is linked to a Queue Head, which is entered in either the
  10115. + * non-periodic or periodic schedule for execution. When a QTD is chosen for
  10116. + * execution, some or all of its transactions may be executed. After
  10117. + * execution, the state of the QTD is updated. The QTD may be retired if all
  10118. + * its transactions are complete or if an error occurred. Otherwise, it
  10119. + * remains in the schedule so more transactions can be executed later.
  10120. + */
  10121. +struct dwc_otg_qh;
  10122. +typedef struct dwc_otg_qtd {
  10123. + /**
  10124. + * Determines the PID of the next data packet for the data phase of
  10125. + * control transfers. Ignored for other transfer types.<br>
  10126. + * One of the following values:
  10127. + * - DWC_OTG_HC_PID_DATA0
  10128. + * - DWC_OTG_HC_PID_DATA1
  10129. + */
  10130. + uint8_t data_toggle;
  10131. +
  10132. + /** Current phase for control transfers (Setup, Data, or Status). */
  10133. + dwc_otg_control_phase_e control_phase;
  10134. +
  10135. + /** Keep track of the current split type
  10136. + * for FS/LS endpoints on a HS Hub */
  10137. + uint8_t complete_split;
  10138. +
  10139. + /** How many bytes transferred during SSPLIT OUT */
  10140. + uint32_t ssplit_out_xfer_count;
  10141. +
  10142. + /**
  10143. + * Holds the number of bus errors that have occurred for a transaction
  10144. + * within this transfer.
  10145. + */
  10146. + uint8_t error_count;
  10147. +
  10148. + /**
  10149. + * Index of the next frame descriptor for an isochronous transfer. A
  10150. + * frame descriptor describes the buffer position and length of the
  10151. + * data to be transferred in the next scheduled (micro)frame of an
  10152. + * isochronous transfer. It also holds status for that transaction.
  10153. + * The frame index starts at 0.
  10154. + */
  10155. + int isoc_frame_index;
  10156. +
  10157. + /** Position of the ISOC split on full/low speed */
  10158. + uint8_t isoc_split_pos;
  10159. +
  10160. + /** Position of the ISOC split in the buffer for the current frame */
  10161. + uint16_t isoc_split_offset;
  10162. +
  10163. + /** URB for this transfer */
  10164. + struct urb *urb;
  10165. +
  10166. + /** This list of QTDs */
  10167. + struct list_head qtd_list_entry;
  10168. +
  10169. + /* Field to track the qh pointer */
  10170. + struct dwc_otg_qh *qtd_qh_ptr;
  10171. +} dwc_otg_qtd_t;
  10172. +
  10173. +/**
  10174. + * A Queue Head (QH) holds the static characteristics of an endpoint and
  10175. + * maintains a list of transfers (QTDs) for that endpoint. A QH structure may
  10176. + * be entered in either the non-periodic or periodic schedule.
  10177. + */
  10178. +typedef struct dwc_otg_qh {
  10179. + /**
  10180. + * Endpoint type.
  10181. + * One of the following values:
  10182. + * - USB_ENDPOINT_XFER_CONTROL
  10183. + * - USB_ENDPOINT_XFER_ISOC
  10184. + * - USB_ENDPOINT_XFER_BULK
  10185. + * - USB_ENDPOINT_XFER_INT
  10186. + */
  10187. + uint8_t ep_type;
  10188. + uint8_t ep_is_in;
  10189. +
  10190. + /** wMaxPacketSize Field of Endpoint Descriptor. */
  10191. + uint16_t maxp;
  10192. +
  10193. + /**
  10194. + * Determines the PID of the next data packet for non-control
  10195. + * transfers. Ignored for control transfers.<br>
  10196. + * One of the following values:
  10197. + * - DWC_OTG_HC_PID_DATA0
  10198. + * - DWC_OTG_HC_PID_DATA1
  10199. + */
  10200. + uint8_t data_toggle;
  10201. +
  10202. + /** Ping state if 1. */
  10203. + uint8_t ping_state;
  10204. +
  10205. + /**
  10206. + * List of QTDs for this QH.
  10207. + */
  10208. + struct list_head qtd_list;
  10209. +
  10210. + /** Host channel currently processing transfers for this QH. */
  10211. + dwc_hc_t *channel;
  10212. +
  10213. + /** QTD currently assigned to a host channel for this QH. */
  10214. + dwc_otg_qtd_t *qtd_in_process;
  10215. +
  10216. + /** Full/low speed endpoint on high-speed hub requires split. */
  10217. + uint8_t do_split;
  10218. +
  10219. + /** @name Periodic schedule information */
  10220. + /** @{ */
  10221. +
  10222. + /** Bandwidth in microseconds per (micro)frame. */
  10223. + uint8_t usecs;
  10224. +
  10225. + /** Interval between transfers in (micro)frames. */
  10226. + uint16_t interval;
  10227. +
  10228. + /**
  10229. + * (micro)frame to initialize a periodic transfer. The transfer
  10230. + * executes in the following (micro)frame.
  10231. + */
  10232. + uint16_t sched_frame;
  10233. +
  10234. + /** (micro)frame at which last start split was initialized. */
  10235. + uint16_t start_split_frame;
  10236. +
  10237. + /** @} */
  10238. +
  10239. + uint16_t speed;
  10240. + uint16_t frame_usecs[8];
  10241. + /** Entry for QH in either the periodic or non-periodic schedule. */
  10242. + struct list_head qh_list_entry;
  10243. +} dwc_otg_qh_t;
  10244. +
  10245. +/**
  10246. + * This structure holds the state of the HCD, including the non-periodic and
  10247. + * periodic schedules.
  10248. + */
  10249. +typedef struct dwc_otg_hcd {
  10250. + spinlock_t lock;
  10251. +
  10252. + /** DWC OTG Core Interface Layer */
  10253. + dwc_otg_core_if_t *core_if;
  10254. +
  10255. + /** Internal DWC HCD Flags */
  10256. + volatile union dwc_otg_hcd_internal_flags {
  10257. + uint32_t d32;
  10258. + struct {
  10259. + unsigned port_connect_status_change : 1;
  10260. + unsigned port_connect_status : 1;
  10261. + unsigned port_reset_change : 1;
  10262. + unsigned port_enable_change : 1;
  10263. + unsigned port_suspend_change : 1;
  10264. + unsigned port_over_current_change : 1;
  10265. + unsigned reserved : 27;
  10266. + } b;
  10267. + } flags;
  10268. +
  10269. + /**
  10270. + * Inactive items in the non-periodic schedule. This is a list of
  10271. + * Queue Heads. Transfers associated with these Queue Heads are not
  10272. + * currently assigned to a host channel.
  10273. + */
  10274. + struct list_head non_periodic_sched_inactive;
  10275. +
  10276. + /**
  10277. + * Deferred items in the non-periodic schedule. This is a list of
  10278. + * Queue Heads. Transfers associated with these Queue Heads are not
  10279. + * currently assigned to a host channel.
  10280. + * When we get an NAK, the QH goes here.
  10281. + */
  10282. + struct list_head non_periodic_sched_deferred;
  10283. +
  10284. + /**
  10285. + * Active items in the non-periodic schedule. This is a list of
  10286. + * Queue Heads. Transfers associated with these Queue Heads are
  10287. + * currently assigned to a host channel.
  10288. + */
  10289. + struct list_head non_periodic_sched_active;
  10290. +
  10291. + /**
  10292. + * Pointer to the next Queue Head to process in the active
  10293. + * non-periodic schedule.
  10294. + */
  10295. + struct list_head *non_periodic_qh_ptr;
  10296. +
  10297. + /**
  10298. + * Inactive items in the periodic schedule. This is a list of QHs for
  10299. + * periodic transfers that are _not_ scheduled for the next frame.
  10300. + * Each QH in the list has an interval counter that determines when it
  10301. + * needs to be scheduled for execution. This scheduling mechanism
  10302. + * allows only a simple calculation for periodic bandwidth used (i.e.
  10303. + * must assume that all periodic transfers may need to execute in the
  10304. + * same frame). However, it greatly simplifies scheduling and should
  10305. + * be sufficient for the vast majority of OTG hosts, which need to
  10306. + * connect to a small number of peripherals at one time.
  10307. + *
  10308. + * Items move from this list to periodic_sched_ready when the QH
  10309. + * interval counter is 0 at SOF.
  10310. + */
  10311. + struct list_head periodic_sched_inactive;
  10312. +
  10313. + /**
  10314. + * List of periodic QHs that are ready for execution in the next
  10315. + * frame, but have not yet been assigned to host channels.
  10316. + *
  10317. + * Items move from this list to periodic_sched_assigned as host
  10318. + * channels become available during the current frame.
  10319. + */
  10320. + struct list_head periodic_sched_ready;
  10321. +
  10322. + /**
  10323. + * List of periodic QHs to be executed in the next frame that are
  10324. + * assigned to host channels.
  10325. + *
  10326. + * Items move from this list to periodic_sched_queued as the
  10327. + * transactions for the QH are queued to the DWC_otg controller.
  10328. + */
  10329. + struct list_head periodic_sched_assigned;
  10330. +
  10331. + /**
  10332. + * List of periodic QHs that have been queued for execution.
  10333. + *
  10334. + * Items move from this list to either periodic_sched_inactive or
  10335. + * periodic_sched_ready when the channel associated with the transfer
  10336. + * is released. If the interval for the QH is 1, the item moves to
  10337. + * periodic_sched_ready because it must be rescheduled for the next
  10338. + * frame. Otherwise, the item moves to periodic_sched_inactive.
  10339. + */
  10340. + struct list_head periodic_sched_queued;
  10341. +
  10342. + /**
  10343. + * Total bandwidth claimed so far for periodic transfers. This value
  10344. + * is in microseconds per (micro)frame. The assumption is that all
  10345. + * periodic transfers may occur in the same (micro)frame.
  10346. + */
  10347. + uint16_t periodic_usecs;
  10348. +
  10349. + /**
  10350. + * Total bandwidth claimed so far for all periodic transfers
  10351. + * in a frame.
  10352. + * This will include a mixture of HS and FS transfers.
  10353. + * Units are microseconds per (micro)frame.
  10354. + * We have a budget per frame and have to schedule
  10355. + * transactions accordingly.
  10356. + * Watch out for the fact that things are actually scheduled for the
  10357. + * "next frame".
  10358. + */
  10359. + uint16_t frame_usecs[8];
  10360. +
  10361. + /**
  10362. + * Frame number read from the core at SOF. The value ranges from 0 to
  10363. + * DWC_HFNUM_MAX_FRNUM.
  10364. + */
  10365. + uint16_t frame_number;
  10366. +
  10367. + /**
  10368. + * Free host channels in the controller. This is a list of
  10369. + * dwc_hc_t items.
  10370. + */
  10371. + struct list_head free_hc_list;
  10372. +
  10373. + /**
  10374. + * Number of available host channels.
  10375. + */
  10376. + int available_host_channels;
  10377. +
  10378. + /**
  10379. + * Array of pointers to the host channel descriptors. Allows accessing
  10380. + * a host channel descriptor given the host channel number. This is
  10381. + * useful in interrupt handlers.
  10382. + */
  10383. + dwc_hc_t *hc_ptr_array[MAX_EPS_CHANNELS];
  10384. +
  10385. + /**
  10386. + * Buffer to use for any data received during the status phase of a
  10387. + * control transfer. Normally no data is transferred during the status
  10388. + * phase. This buffer is used as a bit bucket.
  10389. + */
  10390. + uint8_t *status_buf;
  10391. +
  10392. + /**
  10393. + * DMA address for status_buf.
  10394. + */
  10395. + dma_addr_t status_buf_dma;
  10396. +#define DWC_OTG_HCD_STATUS_BUF_SIZE 64
  10397. +
  10398. + /**
  10399. + * Structure to allow starting the HCD in a non-interrupt context
  10400. + * during an OTG role change.
  10401. + */
  10402. + struct work_struct start_work;
  10403. + struct usb_hcd *_p;
  10404. +
  10405. + /**
  10406. + * Connection timer. An OTG host must display a message if the device
  10407. + * does not connect. Started when the VBus power is turned on via
  10408. + * sysfs attribute "buspower".
  10409. + */
  10410. + struct timer_list conn_timer;
  10411. +
  10412. + /* Tasket to do a reset */
  10413. + struct tasklet_struct *reset_tasklet;
  10414. +
  10415. +#ifdef DEBUG
  10416. + uint32_t frrem_samples;
  10417. + uint64_t frrem_accum;
  10418. +
  10419. + uint32_t hfnum_7_samples_a;
  10420. + uint64_t hfnum_7_frrem_accum_a;
  10421. + uint32_t hfnum_0_samples_a;
  10422. + uint64_t hfnum_0_frrem_accum_a;
  10423. + uint32_t hfnum_other_samples_a;
  10424. + uint64_t hfnum_other_frrem_accum_a;
  10425. +
  10426. + uint32_t hfnum_7_samples_b;
  10427. + uint64_t hfnum_7_frrem_accum_b;
  10428. + uint32_t hfnum_0_samples_b;
  10429. + uint64_t hfnum_0_frrem_accum_b;
  10430. + uint32_t hfnum_other_samples_b;
  10431. + uint64_t hfnum_other_frrem_accum_b;
  10432. +#endif
  10433. +
  10434. +} dwc_otg_hcd_t;
  10435. +
  10436. +/** Gets the dwc_otg_hcd from a struct usb_hcd */
  10437. +static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
  10438. +{
  10439. + return (dwc_otg_hcd_t *)(hcd->hcd_priv);
  10440. +}
  10441. +
  10442. +/** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */
  10443. +static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t *dwc_otg_hcd)
  10444. +{
  10445. + return container_of((void *)dwc_otg_hcd, struct usb_hcd, hcd_priv);
  10446. +}
  10447. +
  10448. +/** @name HCD Create/Destroy Functions */
  10449. +/** @{ */
  10450. +extern int __devinit dwc_otg_hcd_init(struct device *_dev, dwc_otg_device_t * dwc_otg_device);
  10451. +extern void dwc_otg_hcd_remove(struct device *_dev);
  10452. +/** @} */
  10453. +
  10454. +/** @name Linux HC Driver API Functions */
  10455. +/** @{ */
  10456. +
  10457. +extern int dwc_otg_hcd_start(struct usb_hcd *hcd);
  10458. +extern void dwc_otg_hcd_stop(struct usb_hcd *hcd);
  10459. +extern int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd);
  10460. +extern void dwc_otg_hcd_free(struct usb_hcd *hcd);
  10461. +
  10462. +extern int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd,
  10463. + struct urb *urb,
  10464. + gfp_t mem_flags);
  10465. +extern int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd,
  10466. + struct urb *urb,
  10467. + int status);
  10468. +extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd);
  10469. +
  10470. +extern void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
  10471. + struct usb_host_endpoint *ep);
  10472. +
  10473. +extern int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd,
  10474. + char *buf);
  10475. +extern int dwc_otg_hcd_hub_control(struct usb_hcd *hcd,
  10476. + u16 typeReq,
  10477. + u16 wValue,
  10478. + u16 wIndex,
  10479. + char *buf,
  10480. + u16 wLength);
  10481. +
  10482. +/** @} */
  10483. +
  10484. +/** @name Transaction Execution Functions */
  10485. +/** @{ */
  10486. +extern dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t *_hcd);
  10487. +extern void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t *_hcd,
  10488. + dwc_otg_transaction_type_e _tr_type);
  10489. +extern void dwc_otg_hcd_complete_urb(dwc_otg_hcd_t *_hcd, struct urb *_urb,
  10490. + int _status);
  10491. +/** @} */
  10492. +
  10493. +/** @name Interrupt Handler Functions */
  10494. +/** @{ */
  10495. +extern int32_t dwc_otg_hcd_handle_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10496. +extern int32_t dwc_otg_hcd_handle_sof_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10497. +extern int32_t dwc_otg_hcd_handle_rx_status_q_level_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10498. +extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10499. +extern int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10500. +extern int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(dwc_otg_hcd_t *_dwc_otg_hcd);
  10501. +extern int32_t dwc_otg_hcd_handle_port_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10502. +extern int32_t dwc_otg_hcd_handle_conn_id_status_change_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10503. +extern int32_t dwc_otg_hcd_handle_disconnect_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10504. +extern int32_t dwc_otg_hcd_handle_hc_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10505. +extern int32_t dwc_otg_hcd_handle_hc_n_intr (dwc_otg_hcd_t *_dwc_otg_hcd, uint32_t _num);
  10506. +extern int32_t dwc_otg_hcd_handle_session_req_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10507. +extern int32_t dwc_otg_hcd_handle_wakeup_detected_intr (dwc_otg_hcd_t *_dwc_otg_hcd);
  10508. +/** @} */
  10509. +
  10510. +
  10511. +/** @name Schedule Queue Functions */
  10512. +/** @{ */
  10513. +
  10514. +/* Implemented in dwc_otg_hcd_queue.c */
  10515. +extern dwc_otg_qh_t *dwc_otg_hcd_qh_create (dwc_otg_hcd_t *_hcd, struct urb *_urb);
  10516. +extern void dwc_otg_hcd_qh_init (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_urb);
  10517. +extern void dwc_otg_hcd_qh_free (dwc_otg_qh_t *_qh);
  10518. +extern int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh);
  10519. +extern void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh);
  10520. +extern void dwc_otg_hcd_qh_deactivate (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int sched_csplit);
  10521. +extern int dwc_otg_hcd_qh_deferr (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int delay);
  10522. +
  10523. +/** Remove and free a QH */
  10524. +static inline void dwc_otg_hcd_qh_remove_and_free (dwc_otg_hcd_t *_hcd,
  10525. + dwc_otg_qh_t *_qh)
  10526. +{
  10527. + dwc_otg_hcd_qh_remove (_hcd, _qh);
  10528. + dwc_otg_hcd_qh_free (_qh);
  10529. +}
  10530. +
  10531. +/** Allocates memory for a QH structure.
  10532. + * @return Returns the memory allocate or NULL on error. */
  10533. +static inline dwc_otg_qh_t *dwc_otg_hcd_qh_alloc (void)
  10534. +{
  10535. +#ifdef _SC_BUILD_
  10536. + return (dwc_otg_qh_t *) kmalloc (sizeof(dwc_otg_qh_t), GFP_ATOMIC);
  10537. +#else
  10538. + return (dwc_otg_qh_t *) kmalloc (sizeof(dwc_otg_qh_t), GFP_KERNEL);
  10539. +#endif
  10540. +}
  10541. +
  10542. +extern dwc_otg_qtd_t *dwc_otg_hcd_qtd_create (struct urb *urb);
  10543. +extern void dwc_otg_hcd_qtd_init (dwc_otg_qtd_t *qtd, struct urb *urb);
  10544. +extern int dwc_otg_hcd_qtd_add (dwc_otg_qtd_t *qtd, dwc_otg_hcd_t *dwc_otg_hcd);
  10545. +
  10546. +/** Allocates memory for a QTD structure.
  10547. + * @return Returns the memory allocate or NULL on error. */
  10548. +static inline dwc_otg_qtd_t *dwc_otg_hcd_qtd_alloc (void)
  10549. +{
  10550. +#ifdef _SC_BUILD_
  10551. + return (dwc_otg_qtd_t *) kmalloc (sizeof(dwc_otg_qtd_t), GFP_ATOMIC);
  10552. +#else
  10553. + return (dwc_otg_qtd_t *) kmalloc (sizeof(dwc_otg_qtd_t), GFP_KERNEL);
  10554. +#endif
  10555. +}
  10556. +
  10557. +/** Frees the memory for a QTD structure. QTD should already be removed from
  10558. + * list.
  10559. + * @param[in] _qtd QTD to free.*/
  10560. +static inline void dwc_otg_hcd_qtd_free (dwc_otg_qtd_t *_qtd)
  10561. +{
  10562. + kfree (_qtd);
  10563. +}
  10564. +
  10565. +/** Removes a QTD from list.
  10566. + * @param[in] _qtd QTD to remove from list. */
  10567. +static inline void dwc_otg_hcd_qtd_remove (dwc_otg_qtd_t *_qtd)
  10568. +{
  10569. + unsigned long flags;
  10570. + local_irq_save (flags);
  10571. + list_del (&_qtd->qtd_list_entry);
  10572. + local_irq_restore (flags);
  10573. +}
  10574. +
  10575. +/** Remove and free a QTD */
  10576. +static inline void dwc_otg_hcd_qtd_remove_and_free (dwc_otg_qtd_t *_qtd)
  10577. +{
  10578. + dwc_otg_hcd_qtd_remove (_qtd);
  10579. + dwc_otg_hcd_qtd_free (_qtd);
  10580. +}
  10581. +
  10582. +/** @} */
  10583. +
  10584. +
  10585. +/** @name Internal Functions */
  10586. +/** @{ */
  10587. +dwc_otg_qh_t *dwc_urb_to_qh(struct urb *_urb);
  10588. +void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t *_hcd);
  10589. +void dwc_otg_hcd_dump_state(dwc_otg_hcd_t *_hcd);
  10590. +/** @} */
  10591. +
  10592. +
  10593. +/** Gets the usb_host_endpoint associated with an URB. */
  10594. +static inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *_urb)
  10595. +{
  10596. + struct usb_device *dev = _urb->dev;
  10597. + int ep_num = usb_pipeendpoint(_urb->pipe);
  10598. + if (usb_pipein(_urb->pipe))
  10599. + return dev->ep_in[ep_num];
  10600. + else
  10601. + return dev->ep_out[ep_num];
  10602. +}
  10603. +
  10604. +/**
  10605. + * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
  10606. + * qualified with its direction (possible 32 endpoints per device).
  10607. + */
  10608. +#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) \
  10609. + ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
  10610. + ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
  10611. +
  10612. +/** Gets the QH that contains the list_head */
  10613. +#define dwc_list_to_qh(_list_head_ptr_) (container_of(_list_head_ptr_,dwc_otg_qh_t,qh_list_entry))
  10614. +
  10615. +/** Gets the QTD that contains the list_head */
  10616. +#define dwc_list_to_qtd(_list_head_ptr_) (container_of(_list_head_ptr_,dwc_otg_qtd_t,qtd_list_entry))
  10617. +
  10618. +/** Check if QH is non-periodic */
  10619. +#define dwc_qh_is_non_per(_qh_ptr_) ((_qh_ptr_->ep_type == USB_ENDPOINT_XFER_BULK) || \
  10620. + (_qh_ptr_->ep_type == USB_ENDPOINT_XFER_CONTROL))
  10621. +
  10622. +/** High bandwidth multiplier as encoded in highspeed endpoint descriptors */
  10623. +#define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
  10624. +
  10625. +/** Packet size for any kind of endpoint descriptor */
  10626. +#define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
  10627. +
  10628. +/**
  10629. + * Returns true if _frame1 is less than or equal to _frame2. The comparison is
  10630. + * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the
  10631. + * frame number when the max frame number is reached.
  10632. + */
  10633. +static inline int dwc_frame_num_le(uint16_t _frame1, uint16_t _frame2)
  10634. +{
  10635. + return ((_frame2 - _frame1) & DWC_HFNUM_MAX_FRNUM) <=
  10636. + (DWC_HFNUM_MAX_FRNUM >> 1);
  10637. +}
  10638. +
  10639. +/**
  10640. + * Returns true if _frame1 is greater than _frame2. The comparison is done
  10641. + * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame
  10642. + * number when the max frame number is reached.
  10643. + */
  10644. +static inline int dwc_frame_num_gt(uint16_t _frame1, uint16_t _frame2)
  10645. +{
  10646. + return (_frame1 != _frame2) &&
  10647. + (((_frame1 - _frame2) & DWC_HFNUM_MAX_FRNUM) <
  10648. + (DWC_HFNUM_MAX_FRNUM >> 1));
  10649. +}
  10650. +
  10651. +/**
  10652. + * Increments _frame by the amount specified by _inc. The addition is done
  10653. + * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value.
  10654. + */
  10655. +static inline uint16_t dwc_frame_num_inc(uint16_t _frame, uint16_t _inc)
  10656. +{
  10657. + return (_frame + _inc) & DWC_HFNUM_MAX_FRNUM;
  10658. +}
  10659. +
  10660. +static inline uint16_t dwc_full_frame_num (uint16_t _frame)
  10661. +{
  10662. + return ((_frame) & DWC_HFNUM_MAX_FRNUM) >> 3;
  10663. +}
  10664. +
  10665. +static inline uint16_t dwc_micro_frame_num (uint16_t _frame)
  10666. +{
  10667. + return (_frame) & 0x7;
  10668. +}
  10669. +
  10670. +#ifdef DEBUG
  10671. +/**
  10672. + * Macro to sample the remaining PHY clocks left in the current frame. This
  10673. + * may be used during debugging to determine the average time it takes to
  10674. + * execute sections of code. There are two possible sample points, "a" and
  10675. + * "b", so the _letter argument must be one of these values.
  10676. + *
  10677. + * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For
  10678. + * example, "cat /sys/devices/lm0/hcd_frrem".
  10679. + */
  10680. +#define dwc_sample_frrem(_hcd, _qh, _letter) \
  10681. +{ \
  10682. + hfnum_data_t hfnum; \
  10683. + dwc_otg_qtd_t *qtd; \
  10684. + qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry); \
  10685. + if (usb_pipeint(qtd->urb->pipe) && _qh->start_split_frame != 0 && !qtd->complete_split) { \
  10686. + hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum); \
  10687. + switch (hfnum.b.frnum & 0x7) { \
  10688. + case 7: \
  10689. + _hcd->hfnum_7_samples_##_letter++; \
  10690. + _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \
  10691. + break; \
  10692. + case 0: \
  10693. + _hcd->hfnum_0_samples_##_letter++; \
  10694. + _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \
  10695. + break; \
  10696. + default: \
  10697. + _hcd->hfnum_other_samples_##_letter++; \
  10698. + _hcd->hfnum_other_frrem_accum_##_letter += hfnum.b.frrem; \
  10699. + break; \
  10700. + } \
  10701. + } \
  10702. +}
  10703. +#else // DEBUG
  10704. +#define dwc_sample_frrem(_hcd, _qh, _letter)
  10705. +#endif // DEBUG
  10706. +#endif // __DWC_HCD_H__
  10707. +#endif /* DWC_DEVICE_ONLY */
  10708. diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
  10709. new file mode 100644
  10710. index 0000000..834b5e0
  10711. --- /dev/null
  10712. +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c
  10713. @@ -0,0 +1,1841 @@
  10714. +/* ==========================================================================
  10715. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd_intr.c $
  10716. + * $Revision: 1.1.1.1 $
  10717. + * $Date: 2009-04-17 06:15:34 $
  10718. + * $Change: 553126 $
  10719. + *
  10720. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  10721. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  10722. + * otherwise expressly agreed to in writing between Synopsys and you.
  10723. + *
  10724. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  10725. + * any End User Software License Agreement or Agreement for Licensed Product
  10726. + * with Synopsys or any supplement thereto. You are permitted to use and
  10727. + * redistribute this Software in source and binary forms, with or without
  10728. + * modification, provided that redistributions of source code must retain this
  10729. + * notice. You may not view, use, disclose, copy or distribute this file or
  10730. + * any information contained herein except pursuant to this license grant from
  10731. + * Synopsys. If you do not agree with this notice, including the disclaimer
  10732. + * below, then you are not authorized to use the Software.
  10733. + *
  10734. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  10735. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  10736. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  10737. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  10738. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  10739. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  10740. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  10741. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  10742. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  10743. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  10744. + * DAMAGE.
  10745. + * ========================================================================== */
  10746. +#ifndef DWC_DEVICE_ONLY
  10747. +
  10748. +#include "dwc_otg_driver.h"
  10749. +#include "dwc_otg_hcd.h"
  10750. +#include "dwc_otg_regs.h"
  10751. +
  10752. +const int erratum_usb09_patched = 0;
  10753. +const int deferral_on = 1;
  10754. +const int nak_deferral_delay = 8;
  10755. +const int nyet_deferral_delay = 1;
  10756. +/** @file
  10757. + * This file contains the implementation of the HCD Interrupt handlers.
  10758. + */
  10759. +
  10760. +/** This function handles interrupts for the HCD. */
  10761. +int32_t dwc_otg_hcd_handle_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
  10762. +{
  10763. + int retval = 0;
  10764. +
  10765. + dwc_otg_core_if_t *core_if = _dwc_otg_hcd->core_if;
  10766. + gintsts_data_t gintsts;
  10767. +#ifdef DEBUG
  10768. + dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
  10769. +#endif
  10770. +
  10771. + /* Check if HOST Mode */
  10772. + if (dwc_otg_is_host_mode(core_if)) {
  10773. + gintsts.d32 = dwc_otg_read_core_intr(core_if);
  10774. + if (!gintsts.d32) {
  10775. + return 0;
  10776. + }
  10777. +
  10778. +#ifdef DEBUG
  10779. + /* Don't print debug message in the interrupt handler on SOF */
  10780. +# ifndef DEBUG_SOF
  10781. + if (gintsts.d32 != DWC_SOF_INTR_MASK)
  10782. +# endif
  10783. + DWC_DEBUGPL (DBG_HCD, "\n");
  10784. +#endif
  10785. +
  10786. +#ifdef DEBUG
  10787. +# ifndef DEBUG_SOF
  10788. + if (gintsts.d32 != DWC_SOF_INTR_MASK)
  10789. +# endif
  10790. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Interrupt Detected gintsts&gintmsk=0x%08x\n", gintsts.d32);
  10791. +#endif
  10792. +
  10793. + if (gintsts.b.sofintr) {
  10794. + retval |= dwc_otg_hcd_handle_sof_intr (_dwc_otg_hcd);
  10795. + }
  10796. + if (gintsts.b.rxstsqlvl) {
  10797. + retval |= dwc_otg_hcd_handle_rx_status_q_level_intr (_dwc_otg_hcd);
  10798. + }
  10799. + if (gintsts.b.nptxfempty) {
  10800. + retval |= dwc_otg_hcd_handle_np_tx_fifo_empty_intr (_dwc_otg_hcd);
  10801. + }
  10802. + if (gintsts.b.i2cintr) {
  10803. + /** @todo Implement i2cintr handler. */
  10804. + }
  10805. + if (gintsts.b.portintr) {
  10806. + retval |= dwc_otg_hcd_handle_port_intr (_dwc_otg_hcd);
  10807. + }
  10808. + if (gintsts.b.hcintr) {
  10809. + retval |= dwc_otg_hcd_handle_hc_intr (_dwc_otg_hcd);
  10810. + }
  10811. + if (gintsts.b.ptxfempty) {
  10812. + retval |= dwc_otg_hcd_handle_perio_tx_fifo_empty_intr (_dwc_otg_hcd);
  10813. + }
  10814. +#ifdef DEBUG
  10815. +# ifndef DEBUG_SOF
  10816. + if (gintsts.d32 != DWC_SOF_INTR_MASK)
  10817. +# endif
  10818. + {
  10819. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Finished Servicing Interrupts\n");
  10820. + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintsts=0x%08x\n",
  10821. + dwc_read_reg32(&global_regs->gintsts));
  10822. + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintmsk=0x%08x\n",
  10823. + dwc_read_reg32(&global_regs->gintmsk));
  10824. + }
  10825. +#endif
  10826. +
  10827. +#ifdef DEBUG
  10828. +# ifndef DEBUG_SOF
  10829. + if (gintsts.d32 != DWC_SOF_INTR_MASK)
  10830. +# endif
  10831. + DWC_DEBUGPL (DBG_HCD, "\n");
  10832. +#endif
  10833. +
  10834. + }
  10835. +
  10836. + return retval;
  10837. +}
  10838. +
  10839. +#ifdef DWC_TRACK_MISSED_SOFS
  10840. +#warning Compiling code to track missed SOFs
  10841. +#define FRAME_NUM_ARRAY_SIZE 1000
  10842. +/**
  10843. + * This function is for debug only.
  10844. + */
  10845. +static inline void track_missed_sofs(uint16_t _curr_frame_number) {
  10846. + static uint16_t frame_num_array[FRAME_NUM_ARRAY_SIZE];
  10847. + static uint16_t last_frame_num_array[FRAME_NUM_ARRAY_SIZE];
  10848. + static int frame_num_idx = 0;
  10849. + static uint16_t last_frame_num = DWC_HFNUM_MAX_FRNUM;
  10850. + static int dumped_frame_num_array = 0;
  10851. +
  10852. + if (frame_num_idx < FRAME_NUM_ARRAY_SIZE) {
  10853. + if ((((last_frame_num + 1) & DWC_HFNUM_MAX_FRNUM) != _curr_frame_number)) {
  10854. + frame_num_array[frame_num_idx] = _curr_frame_number;
  10855. + last_frame_num_array[frame_num_idx++] = last_frame_num;
  10856. + }
  10857. + } else if (!dumped_frame_num_array) {
  10858. + int i;
  10859. + printk(KERN_EMERG USB_DWC "Frame Last Frame\n");
  10860. + printk(KERN_EMERG USB_DWC "----- ----------\n");
  10861. + for (i = 0; i < FRAME_NUM_ARRAY_SIZE; i++) {
  10862. + printk(KERN_EMERG USB_DWC "0x%04x 0x%04x\n",
  10863. + frame_num_array[i], last_frame_num_array[i]);
  10864. + }
  10865. + dumped_frame_num_array = 1;
  10866. + }
  10867. + last_frame_num = _curr_frame_number;
  10868. +}
  10869. +#endif
  10870. +
  10871. +/**
  10872. + * Handles the start-of-frame interrupt in host mode. Non-periodic
  10873. + * transactions may be queued to the DWC_otg controller for the current
  10874. + * (micro)frame. Periodic transactions may be queued to the controller for the
  10875. + * next (micro)frame.
  10876. + */
  10877. +int32_t dwc_otg_hcd_handle_sof_intr (dwc_otg_hcd_t *_hcd)
  10878. +{
  10879. + hfnum_data_t hfnum;
  10880. + struct list_head *qh_entry;
  10881. + dwc_otg_qh_t *qh;
  10882. + dwc_otg_transaction_type_e tr_type;
  10883. + gintsts_data_t gintsts = {.d32 = 0};
  10884. +
  10885. + hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum);
  10886. +
  10887. +#ifdef DEBUG_SOF
  10888. + DWC_DEBUGPL(DBG_HCD, "--Start of Frame Interrupt--\n");
  10889. +#endif
  10890. +
  10891. + _hcd->frame_number = hfnum.b.frnum;
  10892. +
  10893. +#ifdef DEBUG
  10894. + _hcd->frrem_accum += hfnum.b.frrem;
  10895. + _hcd->frrem_samples++;
  10896. +#endif
  10897. +
  10898. +#ifdef DWC_TRACK_MISSED_SOFS
  10899. + track_missed_sofs(_hcd->frame_number);
  10900. +#endif
  10901. +
  10902. + /* Determine whether any periodic QHs should be executed. */
  10903. + qh_entry = _hcd->periodic_sched_inactive.next;
  10904. + while (qh_entry != &_hcd->periodic_sched_inactive) {
  10905. + qh = list_entry(qh_entry, dwc_otg_qh_t, qh_list_entry);
  10906. + qh_entry = qh_entry->next;
  10907. + if (dwc_frame_num_le(qh->sched_frame, _hcd->frame_number)) {
  10908. + /*
  10909. + * Move QH to the ready list to be executed next
  10910. + * (micro)frame.
  10911. + */
  10912. + list_move(&qh->qh_list_entry, &_hcd->periodic_sched_ready);
  10913. + }
  10914. + }
  10915. +
  10916. + tr_type = dwc_otg_hcd_select_transactions(_hcd);
  10917. + if (tr_type != DWC_OTG_TRANSACTION_NONE) {
  10918. + dwc_otg_hcd_queue_transactions(_hcd, tr_type);
  10919. + }
  10920. +
  10921. + /* Clear interrupt */
  10922. + gintsts.b.sofintr = 1;
  10923. + dwc_write_reg32(&_hcd->core_if->core_global_regs->gintsts, gintsts.d32);
  10924. +
  10925. + return 1;
  10926. +}
  10927. +
  10928. +/** Handles the Rx Status Queue Level Interrupt, which indicates that there is at
  10929. + * least one packet in the Rx FIFO. The packets are moved from the FIFO to
  10930. + * memory if the DWC_otg controller is operating in Slave mode. */
  10931. +int32_t dwc_otg_hcd_handle_rx_status_q_level_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
  10932. +{
  10933. + host_grxsts_data_t grxsts;
  10934. + dwc_hc_t *hc = NULL;
  10935. +
  10936. + DWC_DEBUGPL(DBG_HCD, "--RxStsQ Level Interrupt--\n");
  10937. +
  10938. + grxsts.d32 = dwc_read_reg32(&_dwc_otg_hcd->core_if->core_global_regs->grxstsp);
  10939. +
  10940. + hc = _dwc_otg_hcd->hc_ptr_array[grxsts.b.chnum];
  10941. +
  10942. + /* Packet Status */
  10943. + DWC_DEBUGPL(DBG_HCDV, " Ch num = %d\n", grxsts.b.chnum);
  10944. + DWC_DEBUGPL(DBG_HCDV, " Count = %d\n", grxsts.b.bcnt);
  10945. + DWC_DEBUGPL(DBG_HCDV, " DPID = %d, hc.dpid = %d\n", grxsts.b.dpid, hc->data_pid_start);
  10946. + DWC_DEBUGPL(DBG_HCDV, " PStatus = %d\n", grxsts.b.pktsts);
  10947. +
  10948. + switch (grxsts.b.pktsts) {
  10949. + case DWC_GRXSTS_PKTSTS_IN:
  10950. + /* Read the data into the host buffer. */
  10951. + if (grxsts.b.bcnt > 0) {
  10952. + dwc_otg_read_packet(_dwc_otg_hcd->core_if,
  10953. + hc->xfer_buff,
  10954. + grxsts.b.bcnt);
  10955. +
  10956. + /* Update the HC fields for the next packet received. */
  10957. + hc->xfer_count += grxsts.b.bcnt;
  10958. + hc->xfer_buff += grxsts.b.bcnt;
  10959. + }
  10960. +
  10961. + case DWC_GRXSTS_PKTSTS_IN_XFER_COMP:
  10962. + case DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
  10963. + case DWC_GRXSTS_PKTSTS_CH_HALTED:
  10964. + /* Handled in interrupt, just ignore data */
  10965. + break;
  10966. + default:
  10967. + DWC_ERROR ("RX_STS_Q Interrupt: Unknown status %d\n", grxsts.b.pktsts);
  10968. + break;
  10969. + }
  10970. +
  10971. + return 1;
  10972. +}
  10973. +
  10974. +/** This interrupt occurs when the non-periodic Tx FIFO is half-empty. More
  10975. + * data packets may be written to the FIFO for OUT transfers. More requests
  10976. + * may be written to the non-periodic request queue for IN transfers. This
  10977. + * interrupt is enabled only in Slave mode. */
  10978. +int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
  10979. +{
  10980. + DWC_DEBUGPL(DBG_HCD, "--Non-Periodic TxFIFO Empty Interrupt--\n");
  10981. + dwc_otg_hcd_queue_transactions(_dwc_otg_hcd,
  10982. + DWC_OTG_TRANSACTION_NON_PERIODIC);
  10983. + return 1;
  10984. +}
  10985. +
  10986. +/** This interrupt occurs when the periodic Tx FIFO is half-empty. More data
  10987. + * packets may be written to the FIFO for OUT transfers. More requests may be
  10988. + * written to the periodic request queue for IN transfers. This interrupt is
  10989. + * enabled only in Slave mode. */
  10990. +int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
  10991. +{
  10992. + DWC_DEBUGPL(DBG_HCD, "--Periodic TxFIFO Empty Interrupt--\n");
  10993. + dwc_otg_hcd_queue_transactions(_dwc_otg_hcd,
  10994. + DWC_OTG_TRANSACTION_PERIODIC);
  10995. + return 1;
  10996. +}
  10997. +
  10998. +/** There are multiple conditions that can cause a port interrupt. This function
  10999. + * determines which interrupt conditions have occurred and handles them
  11000. + * appropriately. */
  11001. +int32_t dwc_otg_hcd_handle_port_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
  11002. +{
  11003. + int retval = 0;
  11004. + hprt0_data_t hprt0;
  11005. + hprt0_data_t hprt0_modify;
  11006. +
  11007. + hprt0.d32 = dwc_read_reg32(_dwc_otg_hcd->core_if->host_if->hprt0);
  11008. + hprt0_modify.d32 = dwc_read_reg32(_dwc_otg_hcd->core_if->host_if->hprt0);
  11009. +
  11010. + /* Clear appropriate bits in HPRT0 to clear the interrupt bit in
  11011. + * GINTSTS */
  11012. +
  11013. + hprt0_modify.b.prtena = 0;
  11014. + hprt0_modify.b.prtconndet = 0;
  11015. + hprt0_modify.b.prtenchng = 0;
  11016. + hprt0_modify.b.prtovrcurrchng = 0;
  11017. +
  11018. + /* Port Connect Detected
  11019. + * Set flag and clear if detected */
  11020. + if (hprt0.b.prtconndet) {
  11021. + DWC_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x "
  11022. + "Port Connect Detected--\n", hprt0.d32);
  11023. + _dwc_otg_hcd->flags.b.port_connect_status_change = 1;
  11024. + _dwc_otg_hcd->flags.b.port_connect_status = 1;
  11025. + hprt0_modify.b.prtconndet = 1;
  11026. +
  11027. + /* B-Device has connected, Delete the connection timer. */
  11028. + del_timer( &_dwc_otg_hcd->conn_timer );
  11029. +
  11030. + /* The Hub driver asserts a reset when it sees port connect
  11031. + * status change flag */
  11032. + retval |= 1;
  11033. + }
  11034. +
  11035. + /* Port Enable Changed
  11036. + * Clear if detected - Set internal flag if disabled */
  11037. + if (hprt0.b.prtenchng) {
  11038. + DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
  11039. + "Port Enable Changed--\n", hprt0.d32);
  11040. + hprt0_modify.b.prtenchng = 1;
  11041. + if (hprt0.b.prtena == 1) {
  11042. + int do_reset = 0;
  11043. + dwc_otg_core_params_t *params = _dwc_otg_hcd->core_if->core_params;
  11044. + dwc_otg_core_global_regs_t *global_regs = _dwc_otg_hcd->core_if->core_global_regs;
  11045. + dwc_otg_host_if_t *host_if = _dwc_otg_hcd->core_if->host_if;
  11046. +
  11047. + /* Check if we need to adjust the PHY clock speed for
  11048. + * low power and adjust it */
  11049. + if (params->host_support_fs_ls_low_power)
  11050. + {
  11051. + gusbcfg_data_t usbcfg;
  11052. +
  11053. + usbcfg.d32 = dwc_read_reg32 (&global_regs->gusbcfg);
  11054. +
  11055. + if ((hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED) ||
  11056. + (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_FULL_SPEED))
  11057. + {
  11058. + /*
  11059. + * Low power
  11060. + */
  11061. + hcfg_data_t hcfg;
  11062. + if (usbcfg.b.phylpwrclksel == 0) {
  11063. + /* Set PHY low power clock select for FS/LS devices */
  11064. + usbcfg.b.phylpwrclksel = 1;
  11065. + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
  11066. + do_reset = 1;
  11067. + }
  11068. +
  11069. + hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
  11070. +
  11071. + if ((hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED) &&
  11072. + (params->host_ls_low_power_phy_clk ==
  11073. + DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ))
  11074. + {
  11075. + /* 6 MHZ */
  11076. + DWC_DEBUGPL(DBG_CIL, "FS_PHY programming HCFG to 6 MHz (Low Power)\n");
  11077. + if (hcfg.b.fslspclksel != DWC_HCFG_6_MHZ) {
  11078. + hcfg.b.fslspclksel = DWC_HCFG_6_MHZ;
  11079. + dwc_write_reg32(&host_if->host_global_regs->hcfg,
  11080. + hcfg.d32);
  11081. + do_reset = 1;
  11082. + }
  11083. + }
  11084. + else {
  11085. + /* 48 MHZ */
  11086. + DWC_DEBUGPL(DBG_CIL, "FS_PHY programming HCFG to 48 MHz ()\n");
  11087. + if (hcfg.b.fslspclksel != DWC_HCFG_48_MHZ) {
  11088. + hcfg.b.fslspclksel = DWC_HCFG_48_MHZ;
  11089. + dwc_write_reg32(&host_if->host_global_regs->hcfg,
  11090. + hcfg.d32);
  11091. + do_reset = 1;
  11092. + }
  11093. + }
  11094. + }
  11095. + else {
  11096. + /*
  11097. + * Not low power
  11098. + */
  11099. + if (usbcfg.b.phylpwrclksel == 1) {
  11100. + usbcfg.b.phylpwrclksel = 0;
  11101. + dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
  11102. + do_reset = 1;
  11103. + }
  11104. + }
  11105. +
  11106. + if (do_reset) {
  11107. + tasklet_schedule(_dwc_otg_hcd->reset_tasklet);
  11108. + }
  11109. + }
  11110. +
  11111. + if (!do_reset) {
  11112. + /* Port has been enabled set the reset change flag */
  11113. + _dwc_otg_hcd->flags.b.port_reset_change = 1;
  11114. + }
  11115. +
  11116. + } else {
  11117. + _dwc_otg_hcd->flags.b.port_enable_change = 1;
  11118. + }
  11119. + retval |= 1;
  11120. + }
  11121. +
  11122. + /** Overcurrent Change Interrupt */
  11123. + if (hprt0.b.prtovrcurrchng) {
  11124. + DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
  11125. + "Port Overcurrent Changed--\n", hprt0.d32);
  11126. + _dwc_otg_hcd->flags.b.port_over_current_change = 1;
  11127. + hprt0_modify.b.prtovrcurrchng = 1;
  11128. + retval |= 1;
  11129. + }
  11130. +
  11131. + /* Clear Port Interrupts */
  11132. + dwc_write_reg32(_dwc_otg_hcd->core_if->host_if->hprt0, hprt0_modify.d32);
  11133. +
  11134. + return retval;
  11135. +}
  11136. +
  11137. +
  11138. +/** This interrupt indicates that one or more host channels has a pending
  11139. + * interrupt. There are multiple conditions that can cause each host channel
  11140. + * interrupt. This function determines which conditions have occurred for each
  11141. + * host channel interrupt and handles them appropriately. */
  11142. +int32_t dwc_otg_hcd_handle_hc_intr (dwc_otg_hcd_t *_dwc_otg_hcd)
  11143. +{
  11144. + int i;
  11145. + int retval = 0;
  11146. + haint_data_t haint;
  11147. +
  11148. + /* Clear appropriate bits in HCINTn to clear the interrupt bit in
  11149. + * GINTSTS */
  11150. +
  11151. + haint.d32 = dwc_otg_read_host_all_channels_intr(_dwc_otg_hcd->core_if);
  11152. +
  11153. + for (i=0; i<_dwc_otg_hcd->core_if->core_params->host_channels; i++) {
  11154. + if (haint.b2.chint & (1 << i)) {
  11155. + retval |= dwc_otg_hcd_handle_hc_n_intr (_dwc_otg_hcd, i);
  11156. + }
  11157. + }
  11158. +
  11159. + return retval;
  11160. +}
  11161. +
  11162. +/* Macro used to clear one channel interrupt */
  11163. +#define clear_hc_int(_hc_regs_,_intr_) \
  11164. +do { \
  11165. + hcint_data_t hcint_clear = {.d32 = 0}; \
  11166. + hcint_clear.b._intr_ = 1; \
  11167. + dwc_write_reg32(&((_hc_regs_)->hcint), hcint_clear.d32); \
  11168. +} while (0)
  11169. +
  11170. +/*
  11171. + * Macro used to disable one channel interrupt. Channel interrupts are
  11172. + * disabled when the channel is halted or released by the interrupt handler.
  11173. + * There is no need to handle further interrupts of that type until the
  11174. + * channel is re-assigned. In fact, subsequent handling may cause crashes
  11175. + * because the channel structures are cleaned up when the channel is released.
  11176. + */
  11177. +#define disable_hc_int(_hc_regs_,_intr_) \
  11178. +do { \
  11179. + hcintmsk_data_t hcintmsk = {.d32 = 0}; \
  11180. + hcintmsk.b._intr_ = 1; \
  11181. + dwc_modify_reg32(&((_hc_regs_)->hcintmsk), hcintmsk.d32, 0); \
  11182. +} while (0)
  11183. +
  11184. +/**
  11185. + * Gets the actual length of a transfer after the transfer halts. _halt_status
  11186. + * holds the reason for the halt.
  11187. + *
  11188. + * For IN transfers where _halt_status is DWC_OTG_HC_XFER_COMPLETE,
  11189. + * *_short_read is set to 1 upon return if less than the requested
  11190. + * number of bytes were transferred. Otherwise, *_short_read is set to 0 upon
  11191. + * return. _short_read may also be NULL on entry, in which case it remains
  11192. + * unchanged.
  11193. + */
  11194. +static uint32_t get_actual_xfer_length(dwc_hc_t *_hc,
  11195. + dwc_otg_hc_regs_t *_hc_regs,
  11196. + dwc_otg_qtd_t *_qtd,
  11197. + dwc_otg_halt_status_e _halt_status,
  11198. + int *_short_read)
  11199. +{
  11200. + hctsiz_data_t hctsiz;
  11201. + uint32_t length;
  11202. +
  11203. + if (_short_read != NULL) {
  11204. + *_short_read = 0;
  11205. + }
  11206. + hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
  11207. +
  11208. + if (_halt_status == DWC_OTG_HC_XFER_COMPLETE) {
  11209. + if (_hc->ep_is_in) {
  11210. + length = _hc->xfer_len - hctsiz.b.xfersize;
  11211. + if (_short_read != NULL) {
  11212. + *_short_read = (hctsiz.b.xfersize != 0);
  11213. + }
  11214. + } else if (_hc->qh->do_split) {
  11215. + length = _qtd->ssplit_out_xfer_count;
  11216. + } else {
  11217. + length = _hc->xfer_len;
  11218. + }
  11219. + } else {
  11220. + /*
  11221. + * Must use the hctsiz.pktcnt field to determine how much data
  11222. + * has been transferred. This field reflects the number of
  11223. + * packets that have been transferred via the USB. This is
  11224. + * always an integral number of packets if the transfer was
  11225. + * halted before its normal completion. (Can't use the
  11226. + * hctsiz.xfersize field because that reflects the number of
  11227. + * bytes transferred via the AHB, not the USB).
  11228. + */
  11229. + length = (_hc->start_pkt_count - hctsiz.b.pktcnt) * _hc->max_packet;
  11230. + }
  11231. +
  11232. + return length;
  11233. +}
  11234. +
  11235. +/**
  11236. + * Updates the state of the URB after a Transfer Complete interrupt on the
  11237. + * host channel. Updates the actual_length field of the URB based on the
  11238. + * number of bytes transferred via the host channel. Sets the URB status
  11239. + * if the data transfer is finished.
  11240. + *
  11241. + * @return 1 if the data transfer specified by the URB is completely finished,
  11242. + * 0 otherwise.
  11243. + */
  11244. +static int update_urb_state_xfer_comp(dwc_hc_t *_hc,
  11245. + dwc_otg_hc_regs_t * _hc_regs, struct urb *_urb,
  11246. + dwc_otg_qtd_t * _qtd, int *status)
  11247. +{
  11248. + int xfer_done = 0;
  11249. + int short_read = 0;
  11250. +
  11251. + _urb->actual_length += get_actual_xfer_length(_hc, _hc_regs, _qtd,
  11252. + DWC_OTG_HC_XFER_COMPLETE,
  11253. + &short_read);
  11254. +
  11255. + if (short_read || (_urb->actual_length == _urb->transfer_buffer_length)) {
  11256. + xfer_done = 1;
  11257. + if (short_read && (_urb->transfer_flags & URB_SHORT_NOT_OK)) {
  11258. + *status = -EREMOTEIO;
  11259. + } else {
  11260. + *status = 0;
  11261. + }
  11262. + }
  11263. +
  11264. +#ifdef DEBUG
  11265. + {
  11266. + hctsiz_data_t hctsiz;
  11267. + hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
  11268. + DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
  11269. + __func__, (_hc->ep_is_in ? "IN" : "OUT"), _hc->hc_num);
  11270. + DWC_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", _hc->xfer_len);
  11271. + DWC_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", hctsiz.b.xfersize);
  11272. + DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
  11273. + _urb->transfer_buffer_length);
  11274. + DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", _urb->actual_length);
  11275. + DWC_DEBUGPL(DBG_HCDV, " short_read %d, xfer_done %d\n",
  11276. + short_read, xfer_done);
  11277. + }
  11278. +#endif
  11279. +
  11280. + return xfer_done;
  11281. +}
  11282. +
  11283. +/*
  11284. + * Save the starting data toggle for the next transfer. The data toggle is
  11285. + * saved in the QH for non-control transfers and it's saved in the QTD for
  11286. + * control transfers.
  11287. + */
  11288. +static void save_data_toggle(dwc_hc_t *_hc,
  11289. + dwc_otg_hc_regs_t *_hc_regs,
  11290. + dwc_otg_qtd_t *_qtd)
  11291. +{
  11292. + hctsiz_data_t hctsiz;
  11293. + hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
  11294. +
  11295. + if (_hc->ep_type != DWC_OTG_EP_TYPE_CONTROL) {
  11296. + dwc_otg_qh_t *qh = _hc->qh;
  11297. + if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {
  11298. + qh->data_toggle = DWC_OTG_HC_PID_DATA0;
  11299. + } else {
  11300. + qh->data_toggle = DWC_OTG_HC_PID_DATA1;
  11301. + }
  11302. + } else {
  11303. + if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {
  11304. + _qtd->data_toggle = DWC_OTG_HC_PID_DATA0;
  11305. + } else {
  11306. + _qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
  11307. + }
  11308. + }
  11309. +}
  11310. +
  11311. +/**
  11312. + * Frees the first QTD in the QH's list if free_qtd is 1. For non-periodic
  11313. + * QHs, removes the QH from the active non-periodic schedule. If any QTDs are
  11314. + * still linked to the QH, the QH is added to the end of the inactive
  11315. + * non-periodic schedule. For periodic QHs, removes the QH from the periodic
  11316. + * schedule if no more QTDs are linked to the QH.
  11317. + */
  11318. +static void deactivate_qh(dwc_otg_hcd_t *_hcd,
  11319. + dwc_otg_qh_t *_qh,
  11320. + int free_qtd)
  11321. +{
  11322. + int continue_split = 0;
  11323. + dwc_otg_qtd_t *qtd;
  11324. +
  11325. + DWC_DEBUGPL(DBG_HCDV, " %s(%p,%p,%d)\n", __func__, _hcd, _qh, free_qtd);
  11326. +
  11327. + qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
  11328. +
  11329. + if (qtd->complete_split) {
  11330. + continue_split = 1;
  11331. + }
  11332. + else if ((qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID) ||
  11333. + (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END))
  11334. + {
  11335. + continue_split = 1;
  11336. + }
  11337. +
  11338. + if (free_qtd) {
  11339. + /*
  11340. + * Note that this was previously a call to
  11341. + * dwc_otg_hcd_qtd_remove_and_free(qtd), which frees the qtd.
  11342. + * However, that call frees the qtd memory, and we continue in the
  11343. + * interrupt logic to access it many more times, including writing
  11344. + * to it. With slub debugging on, it is clear that we were writing
  11345. + * to memory we had freed.
  11346. + * Call this instead, and now I have moved the freeing of the memory to
  11347. + * the end of processing this interrupt.
  11348. + */
  11349. + //dwc_otg_hcd_qtd_remove_and_free(qtd);
  11350. + dwc_otg_hcd_qtd_remove(qtd);
  11351. +
  11352. + continue_split = 0;
  11353. + }
  11354. +
  11355. + _qh->channel = NULL;
  11356. + _qh->qtd_in_process = NULL;
  11357. + dwc_otg_hcd_qh_deactivate(_hcd, _qh, continue_split);
  11358. +}
  11359. +
  11360. +/**
  11361. + * Updates the state of an Isochronous URB when the transfer is stopped for
  11362. + * any reason. The fields of the current entry in the frame descriptor array
  11363. + * are set based on the transfer state and the input _halt_status. Completes
  11364. + * the Isochronous URB if all the URB frames have been completed.
  11365. + *
  11366. + * @return DWC_OTG_HC_XFER_COMPLETE if there are more frames remaining to be
  11367. + * transferred in the URB. Otherwise return DWC_OTG_HC_XFER_URB_COMPLETE.
  11368. + */
  11369. +static dwc_otg_halt_status_e
  11370. +update_isoc_urb_state(dwc_otg_hcd_t *_hcd,
  11371. + dwc_hc_t *_hc,
  11372. + dwc_otg_hc_regs_t *_hc_regs,
  11373. + dwc_otg_qtd_t *_qtd,
  11374. + dwc_otg_halt_status_e _halt_status)
  11375. +{
  11376. + struct urb *urb = _qtd->urb;
  11377. + dwc_otg_halt_status_e ret_val = _halt_status;
  11378. + struct usb_iso_packet_descriptor *frame_desc;
  11379. +
  11380. + frame_desc = &urb->iso_frame_desc[_qtd->isoc_frame_index];
  11381. + switch (_halt_status) {
  11382. + case DWC_OTG_HC_XFER_COMPLETE:
  11383. + frame_desc->status = 0;
  11384. + frame_desc->actual_length =
  11385. + get_actual_xfer_length(_hc, _hc_regs, _qtd,
  11386. + _halt_status, NULL);
  11387. + break;
  11388. + case DWC_OTG_HC_XFER_FRAME_OVERRUN:
  11389. + urb->error_count++;
  11390. + if (_hc->ep_is_in) {
  11391. + frame_desc->status = -ENOSR;
  11392. + } else {
  11393. + frame_desc->status = -ECOMM;
  11394. + }
  11395. + frame_desc->actual_length = 0;
  11396. + break;
  11397. + case DWC_OTG_HC_XFER_BABBLE_ERR:
  11398. + urb->error_count++;
  11399. + frame_desc->status = -EOVERFLOW;
  11400. + /* Don't need to update actual_length in this case. */
  11401. + break;
  11402. + case DWC_OTG_HC_XFER_XACT_ERR:
  11403. + urb->error_count++;
  11404. + frame_desc->status = -EPROTO;
  11405. + frame_desc->actual_length =
  11406. + get_actual_xfer_length(_hc, _hc_regs, _qtd,
  11407. + _halt_status, NULL);
  11408. + default:
  11409. + DWC_ERROR("%s: Unhandled _halt_status (%d)\n", __func__,
  11410. + _halt_status);
  11411. + BUG();
  11412. + break;
  11413. + }
  11414. +
  11415. + if (++_qtd->isoc_frame_index == urb->number_of_packets) {
  11416. + /*
  11417. + * urb->status is not used for isoc transfers.
  11418. + * The individual frame_desc statuses are used instead.
  11419. + */
  11420. + dwc_otg_hcd_complete_urb(_hcd, urb, 0);
  11421. + ret_val = DWC_OTG_HC_XFER_URB_COMPLETE;
  11422. + } else {
  11423. + ret_val = DWC_OTG_HC_XFER_COMPLETE;
  11424. + }
  11425. +
  11426. + return ret_val;
  11427. +}
  11428. +
  11429. +/**
  11430. + * Releases a host channel for use by other transfers. Attempts to select and
  11431. + * queue more transactions since at least one host channel is available.
  11432. + *
  11433. + * @param _hcd The HCD state structure.
  11434. + * @param _hc The host channel to release.
  11435. + * @param _qtd The QTD associated with the host channel. This QTD may be freed
  11436. + * if the transfer is complete or an error has occurred.
  11437. + * @param _halt_status Reason the channel is being released. This status
  11438. + * determines the actions taken by this function.
  11439. + */
  11440. +static void release_channel(dwc_otg_hcd_t *_hcd,
  11441. + dwc_hc_t *_hc,
  11442. + dwc_otg_qtd_t *_qtd,
  11443. + dwc_otg_halt_status_e _halt_status,
  11444. + int *must_free)
  11445. +{
  11446. + dwc_otg_transaction_type_e tr_type;
  11447. + int free_qtd;
  11448. + dwc_otg_qh_t * _qh;
  11449. + int deact = 1;
  11450. + int retry_delay = 1;
  11451. + unsigned long flags;
  11452. +
  11453. + DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n", __func__,
  11454. + _hc->hc_num, _halt_status);
  11455. +
  11456. + switch (_halt_status) {
  11457. + case DWC_OTG_HC_XFER_NYET:
  11458. + case DWC_OTG_HC_XFER_NAK:
  11459. + if (_halt_status == DWC_OTG_HC_XFER_NYET) {
  11460. + retry_delay = nyet_deferral_delay;
  11461. + } else {
  11462. + retry_delay = nak_deferral_delay;
  11463. + }
  11464. + free_qtd = 0;
  11465. + if (deferral_on && _hc->do_split) {
  11466. + _qh = _hc->qh;
  11467. + if (_qh) {
  11468. + deact = dwc_otg_hcd_qh_deferr(_hcd, _qh , retry_delay);
  11469. + }
  11470. + }
  11471. + break;
  11472. + case DWC_OTG_HC_XFER_URB_COMPLETE:
  11473. + free_qtd = 1;
  11474. + break;
  11475. + case DWC_OTG_HC_XFER_AHB_ERR:
  11476. + case DWC_OTG_HC_XFER_STALL:
  11477. + case DWC_OTG_HC_XFER_BABBLE_ERR:
  11478. + free_qtd = 1;
  11479. + break;
  11480. + case DWC_OTG_HC_XFER_XACT_ERR:
  11481. + if (_qtd->error_count >= 3) {
  11482. + DWC_DEBUGPL(DBG_HCDV, " Complete URB with transaction error\n");
  11483. + free_qtd = 1;
  11484. + //_qtd->urb->status = -EPROTO;
  11485. + dwc_otg_hcd_complete_urb(_hcd, _qtd->urb, -EPROTO);
  11486. + } else {
  11487. + free_qtd = 0;
  11488. + }
  11489. + break;
  11490. + case DWC_OTG_HC_XFER_URB_DEQUEUE:
  11491. + /*
  11492. + * The QTD has already been removed and the QH has been
  11493. + * deactivated. Don't want to do anything except release the
  11494. + * host channel and try to queue more transfers.
  11495. + */
  11496. + goto cleanup;
  11497. + case DWC_OTG_HC_XFER_NO_HALT_STATUS:
  11498. + DWC_ERROR("%s: No halt_status, channel %d\n", __func__, _hc->hc_num);
  11499. + free_qtd = 0;
  11500. + break;
  11501. + default:
  11502. + free_qtd = 0;
  11503. + break;
  11504. + }
  11505. + if (free_qtd) {
  11506. + /* Only change must_free to true (do not set to zero here -- it is
  11507. + * pre-initialized to zero).
  11508. + */
  11509. + *must_free = 1;
  11510. + }
  11511. + if (deact) {
  11512. + deactivate_qh(_hcd, _hc->qh, free_qtd);
  11513. + }
  11514. + cleanup:
  11515. + /*
  11516. + * Release the host channel for use by other transfers. The cleanup
  11517. + * function clears the channel interrupt enables and conditions, so
  11518. + * there's no need to clear the Channel Halted interrupt separately.
  11519. + */
  11520. + dwc_otg_hc_cleanup(_hcd->core_if, _hc);
  11521. + list_add_tail(&_hc->hc_list_entry, &_hcd->free_hc_list);
  11522. +
  11523. + local_irq_save(flags);
  11524. + _hcd->available_host_channels++;
  11525. + local_irq_restore(flags);
  11526. + /* Try to queue more transfers now that there's a free channel, */
  11527. + /* unless erratum_usb09_patched is set */
  11528. + if (!erratum_usb09_patched) {
  11529. + tr_type = dwc_otg_hcd_select_transactions(_hcd);
  11530. + if (tr_type != DWC_OTG_TRANSACTION_NONE) {
  11531. + dwc_otg_hcd_queue_transactions(_hcd, tr_type);
  11532. + }
  11533. + }
  11534. +}
  11535. +
  11536. +/**
  11537. + * Halts a host channel. If the channel cannot be halted immediately because
  11538. + * the request queue is full, this function ensures that the FIFO empty
  11539. + * interrupt for the appropriate queue is enabled so that the halt request can
  11540. + * be queued when there is space in the request queue.
  11541. + *
  11542. + * This function may also be called in DMA mode. In that case, the channel is
  11543. + * simply released since the core always halts the channel automatically in
  11544. + * DMA mode.
  11545. + */
  11546. +static void halt_channel(dwc_otg_hcd_t *_hcd,
  11547. + dwc_hc_t *_hc,
  11548. + dwc_otg_qtd_t *_qtd,
  11549. + dwc_otg_halt_status_e _halt_status, int *must_free)
  11550. +{
  11551. + if (_hcd->core_if->dma_enable) {
  11552. + release_channel(_hcd, _hc, _qtd, _halt_status, must_free);
  11553. + return;
  11554. + }
  11555. +
  11556. + /* Slave mode processing... */
  11557. + dwc_otg_hc_halt(_hcd->core_if, _hc, _halt_status);
  11558. +
  11559. + if (_hc->halt_on_queue) {
  11560. + gintmsk_data_t gintmsk = {.d32 = 0};
  11561. + dwc_otg_core_global_regs_t *global_regs;
  11562. + global_regs = _hcd->core_if->core_global_regs;
  11563. +
  11564. + if (_hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
  11565. + _hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
  11566. + /*
  11567. + * Make sure the Non-periodic Tx FIFO empty interrupt
  11568. + * is enabled so that the non-periodic schedule will
  11569. + * be processed.
  11570. + */
  11571. + gintmsk.b.nptxfempty = 1;
  11572. + dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
  11573. + } else {
  11574. + /*
  11575. + * Move the QH from the periodic queued schedule to
  11576. + * the periodic assigned schedule. This allows the
  11577. + * halt to be queued when the periodic schedule is
  11578. + * processed.
  11579. + */
  11580. + list_move(&_hc->qh->qh_list_entry,
  11581. + &_hcd->periodic_sched_assigned);
  11582. +
  11583. + /*
  11584. + * Make sure the Periodic Tx FIFO Empty interrupt is
  11585. + * enabled so that the periodic schedule will be
  11586. + * processed.
  11587. + */
  11588. + gintmsk.b.ptxfempty = 1;
  11589. + dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);
  11590. + }
  11591. + }
  11592. +}
  11593. +
  11594. +/**
  11595. + * Performs common cleanup for non-periodic transfers after a Transfer
  11596. + * Complete interrupt. This function should be called after any endpoint type
  11597. + * specific handling is finished to release the host channel.
  11598. + */
  11599. +static void complete_non_periodic_xfer(dwc_otg_hcd_t *_hcd,
  11600. + dwc_hc_t *_hc,
  11601. + dwc_otg_hc_regs_t *_hc_regs,
  11602. + dwc_otg_qtd_t *_qtd,
  11603. + dwc_otg_halt_status_e _halt_status, int *must_free)
  11604. +{
  11605. + hcint_data_t hcint;
  11606. +
  11607. + _qtd->error_count = 0;
  11608. +
  11609. + hcint.d32 = dwc_read_reg32(&_hc_regs->hcint);
  11610. + if (hcint.b.nyet) {
  11611. + /*
  11612. + * Got a NYET on the last transaction of the transfer. This
  11613. + * means that the endpoint should be in the PING state at the
  11614. + * beginning of the next transfer.
  11615. + */
  11616. + _hc->qh->ping_state = 1;
  11617. + clear_hc_int(_hc_regs,nyet);
  11618. + }
  11619. +
  11620. + /*
  11621. + * Always halt and release the host channel to make it available for
  11622. + * more transfers. There may still be more phases for a control
  11623. + * transfer or more data packets for a bulk transfer at this point,
  11624. + * but the host channel is still halted. A channel will be reassigned
  11625. + * to the transfer when the non-periodic schedule is processed after
  11626. + * the channel is released. This allows transactions to be queued
  11627. + * properly via dwc_otg_hcd_queue_transactions, which also enables the
  11628. + * Tx FIFO Empty interrupt if necessary.
  11629. + */
  11630. + if (_hc->ep_is_in) {
  11631. + /*
  11632. + * IN transfers in Slave mode require an explicit disable to
  11633. + * halt the channel. (In DMA mode, this call simply releases
  11634. + * the channel.)
  11635. + */
  11636. + halt_channel(_hcd, _hc, _qtd, _halt_status, must_free);
  11637. + } else {
  11638. + /*
  11639. + * The channel is automatically disabled by the core for OUT
  11640. + * transfers in Slave mode.
  11641. + */
  11642. + release_channel(_hcd, _hc, _qtd, _halt_status, must_free);
  11643. + }
  11644. +}
  11645. +
  11646. +/**
  11647. + * Performs common cleanup for periodic transfers after a Transfer Complete
  11648. + * interrupt. This function should be called after any endpoint type specific
  11649. + * handling is finished to release the host channel.
  11650. + */
  11651. +static void complete_periodic_xfer(dwc_otg_hcd_t *_hcd,
  11652. + dwc_hc_t *_hc,
  11653. + dwc_otg_hc_regs_t *_hc_regs,
  11654. + dwc_otg_qtd_t *_qtd,
  11655. + dwc_otg_halt_status_e _halt_status, int *must_free)
  11656. +{
  11657. + hctsiz_data_t hctsiz;
  11658. + _qtd->error_count = 0;
  11659. +
  11660. + hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
  11661. + if (!_hc->ep_is_in || hctsiz.b.pktcnt == 0) {
  11662. + /* Core halts channel in these cases. */
  11663. + release_channel(_hcd, _hc, _qtd, _halt_status, must_free);
  11664. + } else {
  11665. + /* Flush any outstanding requests from the Tx queue. */
  11666. + halt_channel(_hcd, _hc, _qtd, _halt_status, must_free);
  11667. + }
  11668. +}
  11669. +
  11670. +/**
  11671. + * Handles a host channel Transfer Complete interrupt. This handler may be
  11672. + * called in either DMA mode or Slave mode.
  11673. + */
  11674. +static int32_t handle_hc_xfercomp_intr(dwc_otg_hcd_t *_hcd,
  11675. + dwc_hc_t *_hc,
  11676. + dwc_otg_hc_regs_t *_hc_regs,
  11677. + dwc_otg_qtd_t *_qtd, int *must_free)
  11678. +{
  11679. + int urb_xfer_done;
  11680. + dwc_otg_halt_status_e halt_status = DWC_OTG_HC_XFER_COMPLETE;
  11681. + struct urb *urb = _qtd->urb;
  11682. + int pipe_type = usb_pipetype(urb->pipe);
  11683. + int status = -EINPROGRESS;
  11684. +
  11685. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  11686. + "Transfer Complete--\n", _hc->hc_num);
  11687. +
  11688. + /*
  11689. + * Handle xfer complete on CSPLIT.
  11690. + */
  11691. + if (_hc->qh->do_split) {
  11692. + _qtd->complete_split = 0;
  11693. + }
  11694. +
  11695. + /* Update the QTD and URB states. */
  11696. + switch (pipe_type) {
  11697. + case PIPE_CONTROL:
  11698. + switch (_qtd->control_phase) {
  11699. + case DWC_OTG_CONTROL_SETUP:
  11700. + if (urb->transfer_buffer_length > 0) {
  11701. + _qtd->control_phase = DWC_OTG_CONTROL_DATA;
  11702. + } else {
  11703. + _qtd->control_phase = DWC_OTG_CONTROL_STATUS;
  11704. + }
  11705. + DWC_DEBUGPL(DBG_HCDV, " Control setup transaction done\n");
  11706. + halt_status = DWC_OTG_HC_XFER_COMPLETE;
  11707. + break;
  11708. + case DWC_OTG_CONTROL_DATA: {
  11709. + urb_xfer_done = update_urb_state_xfer_comp(_hc, _hc_regs,urb, _qtd, &status);
  11710. + if (urb_xfer_done) {
  11711. + _qtd->control_phase = DWC_OTG_CONTROL_STATUS;
  11712. + DWC_DEBUGPL(DBG_HCDV, " Control data transfer done\n");
  11713. + } else {
  11714. + save_data_toggle(_hc, _hc_regs, _qtd);
  11715. + }
  11716. + halt_status = DWC_OTG_HC_XFER_COMPLETE;
  11717. + break;
  11718. + }
  11719. + case DWC_OTG_CONTROL_STATUS:
  11720. + DWC_DEBUGPL(DBG_HCDV, " Control transfer complete\n");
  11721. + if (status == -EINPROGRESS) {
  11722. + status = 0;
  11723. + }
  11724. + dwc_otg_hcd_complete_urb(_hcd, urb, status);
  11725. + halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
  11726. + break;
  11727. + }
  11728. +
  11729. + complete_non_periodic_xfer(_hcd, _hc, _hc_regs, _qtd,
  11730. + halt_status, must_free);
  11731. + break;
  11732. + case PIPE_BULK:
  11733. + DWC_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
  11734. + urb_xfer_done = update_urb_state_xfer_comp(_hc, _hc_regs, urb, _qtd, &status);
  11735. + if (urb_xfer_done) {
  11736. + dwc_otg_hcd_complete_urb(_hcd, urb, status);
  11737. + halt_status = DWC_OTG_HC_XFER_URB_COMPLETE;
  11738. + } else {
  11739. + halt_status = DWC_OTG_HC_XFER_COMPLETE;
  11740. + }
  11741. +
  11742. + save_data_toggle(_hc, _hc_regs, _qtd);
  11743. + complete_non_periodic_xfer(_hcd, _hc, _hc_regs, _qtd,halt_status, must_free);
  11744. + break;
  11745. + case PIPE_INTERRUPT:
  11746. + DWC_DEBUGPL(DBG_HCDV, " Interrupt transfer complete\n");
  11747. + update_urb_state_xfer_comp(_hc, _hc_regs, urb, _qtd, &status);
  11748. +
  11749. + /*
  11750. + * Interrupt URB is done on the first transfer complete
  11751. + * interrupt.
  11752. + */
  11753. + dwc_otg_hcd_complete_urb(_hcd, urb, status);
  11754. + save_data_toggle(_hc, _hc_regs, _qtd);
  11755. + complete_periodic_xfer(_hcd, _hc, _hc_regs, _qtd,
  11756. + DWC_OTG_HC_XFER_URB_COMPLETE, must_free);
  11757. + break;
  11758. + case PIPE_ISOCHRONOUS:
  11759. + DWC_DEBUGPL(DBG_HCDV, " Isochronous transfer complete\n");
  11760. + if (_qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_ALL)
  11761. + {
  11762. + halt_status = update_isoc_urb_state(_hcd, _hc, _hc_regs, _qtd,
  11763. + DWC_OTG_HC_XFER_COMPLETE);
  11764. + }
  11765. + complete_periodic_xfer(_hcd, _hc, _hc_regs, _qtd, halt_status, must_free);
  11766. + break;
  11767. + }
  11768. +
  11769. + disable_hc_int(_hc_regs,xfercompl);
  11770. +
  11771. + return 1;
  11772. +}
  11773. +
  11774. +/**
  11775. + * Handles a host channel STALL interrupt. This handler may be called in
  11776. + * either DMA mode or Slave mode.
  11777. + */
  11778. +static int32_t handle_hc_stall_intr(dwc_otg_hcd_t *_hcd,
  11779. + dwc_hc_t *_hc,
  11780. + dwc_otg_hc_regs_t *_hc_regs,
  11781. + dwc_otg_qtd_t *_qtd, int *must_free)
  11782. +{
  11783. + struct urb *urb = _qtd->urb;
  11784. + int pipe_type = usb_pipetype(urb->pipe);
  11785. +
  11786. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  11787. + "STALL Received--\n", _hc->hc_num);
  11788. +
  11789. + if (pipe_type == PIPE_CONTROL) {
  11790. + dwc_otg_hcd_complete_urb(_hcd, _qtd->urb, -EPIPE);
  11791. + }
  11792. +
  11793. + if (pipe_type == PIPE_BULK || pipe_type == PIPE_INTERRUPT) {
  11794. + dwc_otg_hcd_complete_urb(_hcd, _qtd->urb, -EPIPE);
  11795. + /*
  11796. + * USB protocol requires resetting the data toggle for bulk
  11797. + * and interrupt endpoints when a CLEAR_FEATURE(ENDPOINT_HALT)
  11798. + * setup command is issued to the endpoint. Anticipate the
  11799. + * CLEAR_FEATURE command since a STALL has occurred and reset
  11800. + * the data toggle now.
  11801. + */
  11802. + _hc->qh->data_toggle = 0;
  11803. + }
  11804. +
  11805. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_STALL, must_free);
  11806. + disable_hc_int(_hc_regs,stall);
  11807. +
  11808. + return 1;
  11809. +}
  11810. +
  11811. +/*
  11812. + * Updates the state of the URB when a transfer has been stopped due to an
  11813. + * abnormal condition before the transfer completes. Modifies the
  11814. + * actual_length field of the URB to reflect the number of bytes that have
  11815. + * actually been transferred via the host channel.
  11816. + */
  11817. +static void update_urb_state_xfer_intr(dwc_hc_t *_hc,
  11818. + dwc_otg_hc_regs_t *_hc_regs,
  11819. + struct urb *_urb,
  11820. + dwc_otg_qtd_t *_qtd,
  11821. + dwc_otg_halt_status_e _halt_status)
  11822. +{
  11823. + uint32_t bytes_transferred = get_actual_xfer_length(_hc, _hc_regs, _qtd,
  11824. + _halt_status, NULL);
  11825. + _urb->actual_length += bytes_transferred;
  11826. +
  11827. +#ifdef DEBUG
  11828. + {
  11829. + hctsiz_data_t hctsiz;
  11830. + hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
  11831. + DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n",
  11832. + __func__, (_hc->ep_is_in ? "IN" : "OUT"), _hc->hc_num);
  11833. + DWC_DEBUGPL(DBG_HCDV, " _hc->start_pkt_count %d\n", _hc->start_pkt_count);
  11834. + DWC_DEBUGPL(DBG_HCDV, " hctsiz.pktcnt %d\n", hctsiz.b.pktcnt);
  11835. + DWC_DEBUGPL(DBG_HCDV, " _hc->max_packet %d\n", _hc->max_packet);
  11836. + DWC_DEBUGPL(DBG_HCDV, " bytes_transferred %d\n", bytes_transferred);
  11837. + DWC_DEBUGPL(DBG_HCDV, " _urb->actual_length %d\n", _urb->actual_length);
  11838. + DWC_DEBUGPL(DBG_HCDV, " _urb->transfer_buffer_length %d\n",
  11839. + _urb->transfer_buffer_length);
  11840. + }
  11841. +#endif
  11842. +}
  11843. +
  11844. +/**
  11845. + * Handles a host channel NAK interrupt. This handler may be called in either
  11846. + * DMA mode or Slave mode.
  11847. + */
  11848. +static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *_hcd,
  11849. + dwc_hc_t *_hc,
  11850. + dwc_otg_hc_regs_t *_hc_regs,
  11851. + dwc_otg_qtd_t *_qtd, int *must_free)
  11852. +{
  11853. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  11854. + "NAK Received--\n", _hc->hc_num);
  11855. +
  11856. + /*
  11857. + * Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
  11858. + * interrupt. Re-start the SSPLIT transfer.
  11859. + */
  11860. + if (_hc->do_split) {
  11861. + if (_hc->complete_split) {
  11862. + _qtd->error_count = 0;
  11863. + }
  11864. + _qtd->complete_split = 0;
  11865. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK, must_free);
  11866. + goto handle_nak_done;
  11867. + }
  11868. +
  11869. + switch (usb_pipetype(_qtd->urb->pipe)) {
  11870. + case PIPE_CONTROL:
  11871. + case PIPE_BULK:
  11872. + if (_hcd->core_if->dma_enable && _hc->ep_is_in) {
  11873. + /*
  11874. + * NAK interrupts are enabled on bulk/control IN
  11875. + * transfers in DMA mode for the sole purpose of
  11876. + * resetting the error count after a transaction error
  11877. + * occurs. The core will continue transferring data.
  11878. + */
  11879. + _qtd->error_count = 0;
  11880. + goto handle_nak_done;
  11881. + }
  11882. +
  11883. + /*
  11884. + * NAK interrupts normally occur during OUT transfers in DMA
  11885. + * or Slave mode. For IN transfers, more requests will be
  11886. + * queued as request queue space is available.
  11887. + */
  11888. + _qtd->error_count = 0;
  11889. +
  11890. + if (!_hc->qh->ping_state) {
  11891. + update_urb_state_xfer_intr(_hc, _hc_regs, _qtd->urb,
  11892. + _qtd, DWC_OTG_HC_XFER_NAK);
  11893. + save_data_toggle(_hc, _hc_regs, _qtd);
  11894. + if (_qtd->urb->dev->speed == USB_SPEED_HIGH) {
  11895. + _hc->qh->ping_state = 1;
  11896. + }
  11897. + }
  11898. +
  11899. + /*
  11900. + * Halt the channel so the transfer can be re-started from
  11901. + * the appropriate point or the PING protocol will
  11902. + * start/continue.
  11903. + */
  11904. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK, must_free);
  11905. + break;
  11906. + case PIPE_INTERRUPT:
  11907. + _qtd->error_count = 0;
  11908. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NAK, must_free);
  11909. + break;
  11910. + case PIPE_ISOCHRONOUS:
  11911. + /* Should never get called for isochronous transfers. */
  11912. + BUG();
  11913. + break;
  11914. + }
  11915. +
  11916. + handle_nak_done:
  11917. + disable_hc_int(_hc_regs,nak);
  11918. +
  11919. + return 1;
  11920. +}
  11921. +
  11922. +/**
  11923. + * Handles a host channel ACK interrupt. This interrupt is enabled when
  11924. + * performing the PING protocol in Slave mode, when errors occur during
  11925. + * either Slave mode or DMA mode, and during Start Split transactions.
  11926. + */
  11927. +static int32_t handle_hc_ack_intr(dwc_otg_hcd_t *_hcd,
  11928. + dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
  11929. +{
  11930. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  11931. + "ACK Received--\n", _hc->hc_num);
  11932. +
  11933. + if (_hc->do_split) {
  11934. + /*
  11935. + * Handle ACK on SSPLIT.
  11936. + * ACK should not occur in CSPLIT.
  11937. + */
  11938. + if ((!_hc->ep_is_in) && (_hc->data_pid_start != DWC_OTG_HC_PID_SETUP)) {
  11939. + _qtd->ssplit_out_xfer_count = _hc->xfer_len;
  11940. + }
  11941. + if (!(_hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !_hc->ep_is_in)) {
  11942. + /* Don't need complete for isochronous out transfers. */
  11943. + _qtd->complete_split = 1;
  11944. + }
  11945. +
  11946. + /* ISOC OUT */
  11947. + if ((_hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && !_hc->ep_is_in) {
  11948. + switch (_hc->xact_pos) {
  11949. + case DWC_HCSPLIT_XACTPOS_ALL:
  11950. + break;
  11951. + case DWC_HCSPLIT_XACTPOS_END:
  11952. + _qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
  11953. + _qtd->isoc_split_offset = 0;
  11954. + break;
  11955. + case DWC_HCSPLIT_XACTPOS_BEGIN:
  11956. + case DWC_HCSPLIT_XACTPOS_MID:
  11957. + /*
  11958. + * For BEGIN or MID, calculate the length for
  11959. + * the next microframe to determine the correct
  11960. + * SSPLIT token, either MID or END.
  11961. + */
  11962. + do {
  11963. + struct usb_iso_packet_descriptor *frame_desc;
  11964. +
  11965. + frame_desc = &_qtd->urb->iso_frame_desc[_qtd->isoc_frame_index];
  11966. + _qtd->isoc_split_offset += 188;
  11967. +
  11968. + if ((frame_desc->length - _qtd->isoc_split_offset) <= 188) {
  11969. + _qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_END;
  11970. + }
  11971. + else {
  11972. + _qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_MID;
  11973. + }
  11974. +
  11975. + } while(0);
  11976. + break;
  11977. + }
  11978. + } else {
  11979. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_ACK, must_free);
  11980. + }
  11981. + } else {
  11982. + _qtd->error_count = 0;
  11983. +
  11984. + if (_hc->qh->ping_state) {
  11985. + _hc->qh->ping_state = 0;
  11986. + /*
  11987. + * Halt the channel so the transfer can be re-started
  11988. + * from the appropriate point. This only happens in
  11989. + * Slave mode. In DMA mode, the ping_state is cleared
  11990. + * when the transfer is started because the core
  11991. + * automatically executes the PING, then the transfer.
  11992. + */
  11993. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_ACK, must_free);
  11994. + } else {
  11995. + halt_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
  11996. + }
  11997. + }
  11998. +
  11999. + /*
  12000. + * If the ACK occurred when _not_ in the PING state, let the channel
  12001. + * continue transferring data after clearing the error count.
  12002. + */
  12003. +
  12004. + disable_hc_int(_hc_regs,ack);
  12005. +
  12006. + return 1;
  12007. +}
  12008. +
  12009. +/**
  12010. + * Handles a host channel NYET interrupt. This interrupt should only occur on
  12011. + * Bulk and Control OUT endpoints and for complete split transactions. If a
  12012. + * NYET occurs at the same time as a Transfer Complete interrupt, it is
  12013. + * handled in the xfercomp interrupt handler, not here. This handler may be
  12014. + * called in either DMA mode or Slave mode.
  12015. + */
  12016. +static int32_t handle_hc_nyet_intr(dwc_otg_hcd_t *_hcd,
  12017. + dwc_hc_t *_hc,
  12018. + dwc_otg_hc_regs_t *_hc_regs,
  12019. + dwc_otg_qtd_t *_qtd, int *must_free)
  12020. +{
  12021. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  12022. + "NYET Received--\n", _hc->hc_num);
  12023. +
  12024. + /*
  12025. + * NYET on CSPLIT
  12026. + * re-do the CSPLIT immediately on non-periodic
  12027. + */
  12028. + if ((_hc->do_split) && (_hc->complete_split)) {
  12029. + if ((_hc->ep_type == DWC_OTG_EP_TYPE_INTR) ||
  12030. + (_hc->ep_type == DWC_OTG_EP_TYPE_ISOC)) {
  12031. + int frnum = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(_hcd));
  12032. +
  12033. + if (dwc_full_frame_num(frnum) !=
  12034. + dwc_full_frame_num(_hc->qh->sched_frame)) {
  12035. + /*
  12036. + * No longer in the same full speed frame.
  12037. + * Treat this as a transaction error.
  12038. + */
  12039. +#if 0
  12040. + /** @todo Fix system performance so this can
  12041. + * be treated as an error. Right now complete
  12042. + * splits cannot be scheduled precisely enough
  12043. + * due to other system activity, so this error
  12044. + * occurs regularly in Slave mode.
  12045. + */
  12046. + _qtd->error_count++;
  12047. +#endif
  12048. + _qtd->complete_split = 0;
  12049. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_XACT_ERR, must_free);
  12050. + /** @todo add support for isoc release */
  12051. + goto handle_nyet_done;
  12052. + }
  12053. + }
  12054. +
  12055. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NYET, must_free);
  12056. + goto handle_nyet_done;
  12057. + }
  12058. +
  12059. + _hc->qh->ping_state = 1;
  12060. + _qtd->error_count = 0;
  12061. +
  12062. + update_urb_state_xfer_intr(_hc, _hc_regs, _qtd->urb, _qtd,
  12063. + DWC_OTG_HC_XFER_NYET);
  12064. + save_data_toggle(_hc, _hc_regs, _qtd);
  12065. +
  12066. + /*
  12067. + * Halt the channel and re-start the transfer so the PING
  12068. + * protocol will start.
  12069. + */
  12070. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_NYET, must_free);
  12071. +
  12072. +handle_nyet_done:
  12073. + disable_hc_int(_hc_regs,nyet);
  12074. + clear_hc_int(_hc_regs, nyet);
  12075. + return 1;
  12076. +}
  12077. +
  12078. +/**
  12079. + * Handles a host channel babble interrupt. This handler may be called in
  12080. + * either DMA mode or Slave mode.
  12081. + */
  12082. +static int32_t handle_hc_babble_intr(dwc_otg_hcd_t *_hcd,
  12083. + dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
  12084. +{
  12085. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  12086. + "Babble Error--\n", _hc->hc_num);
  12087. + if (_hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
  12088. + dwc_otg_hcd_complete_urb(_hcd, _qtd->urb, -EOVERFLOW);
  12089. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_BABBLE_ERR, must_free);
  12090. + } else {
  12091. + dwc_otg_halt_status_e halt_status;
  12092. + halt_status = update_isoc_urb_state(_hcd, _hc, _hc_regs, _qtd,
  12093. + DWC_OTG_HC_XFER_BABBLE_ERR);
  12094. + halt_channel(_hcd, _hc, _qtd, halt_status, must_free);
  12095. + }
  12096. + disable_hc_int(_hc_regs,bblerr);
  12097. + return 1;
  12098. +}
  12099. +
  12100. +/**
  12101. + * Handles a host channel AHB error interrupt. This handler is only called in
  12102. + * DMA mode.
  12103. + */
  12104. +static int32_t handle_hc_ahberr_intr(dwc_otg_hcd_t *_hcd,
  12105. + dwc_hc_t *_hc,
  12106. + dwc_otg_hc_regs_t *_hc_regs,
  12107. + dwc_otg_qtd_t *_qtd)
  12108. +{
  12109. + hcchar_data_t hcchar;
  12110. + hcsplt_data_t hcsplt;
  12111. + hctsiz_data_t hctsiz;
  12112. + uint32_t hcdma;
  12113. + struct urb *urb = _qtd->urb;
  12114. +
  12115. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  12116. + "AHB Error--\n", _hc->hc_num);
  12117. +
  12118. + hcchar.d32 = dwc_read_reg32(&_hc_regs->hcchar);
  12119. + hcsplt.d32 = dwc_read_reg32(&_hc_regs->hcsplt);
  12120. + hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
  12121. + hcdma = dwc_read_reg32(&_hc_regs->hcdma);
  12122. +
  12123. + DWC_ERROR("AHB ERROR, Channel %d\n", _hc->hc_num);
  12124. + DWC_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
  12125. + DWC_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
  12126. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Enqueue\n");
  12127. + DWC_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe));
  12128. + DWC_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
  12129. + (usb_pipein(urb->pipe) ? "IN" : "OUT"));
  12130. + DWC_ERROR(" Endpoint type: %s\n",
  12131. + ({char *pipetype;
  12132. + switch (usb_pipetype(urb->pipe)) {
  12133. + case PIPE_CONTROL: pipetype = "CONTROL"; break;
  12134. + case PIPE_BULK: pipetype = "BULK"; break;
  12135. + case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
  12136. + case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
  12137. + default: pipetype = "UNKNOWN"; break;
  12138. + }; pipetype;}));
  12139. + DWC_ERROR(" Speed: %s\n",
  12140. + ({char *speed;
  12141. + switch (urb->dev->speed) {
  12142. + case USB_SPEED_HIGH: speed = "HIGH"; break;
  12143. + case USB_SPEED_FULL: speed = "FULL"; break;
  12144. + case USB_SPEED_LOW: speed = "LOW"; break;
  12145. + default: speed = "UNKNOWN"; break;
  12146. + }; speed;}));
  12147. + DWC_ERROR(" Max packet size: %d\n",
  12148. + usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
  12149. + DWC_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length);
  12150. + DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n",
  12151. + urb->transfer_buffer, (void *)(u32)urb->transfer_dma);
  12152. + DWC_ERROR(" Setup buffer: %p, Setup DMA: %p\n",
  12153. + urb->setup_packet, (void *)(u32)urb->setup_dma);
  12154. + DWC_ERROR(" Interval: %d\n", urb->interval);
  12155. +
  12156. + dwc_otg_hcd_complete_urb(_hcd, urb, -EIO);
  12157. +
  12158. + /*
  12159. + * Force a channel halt. Don't call halt_channel because that won't
  12160. + * write to the HCCHARn register in DMA mode to force the halt.
  12161. + */
  12162. + dwc_otg_hc_halt(_hcd->core_if, _hc, DWC_OTG_HC_XFER_AHB_ERR);
  12163. +
  12164. + disable_hc_int(_hc_regs,ahberr);
  12165. + return 1;
  12166. +}
  12167. +
  12168. +/**
  12169. + * Handles a host channel transaction error interrupt. This handler may be
  12170. + * called in either DMA mode or Slave mode.
  12171. + */
  12172. +static int32_t handle_hc_xacterr_intr(dwc_otg_hcd_t *_hcd,
  12173. + dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
  12174. +{
  12175. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  12176. + "Transaction Error--\n", _hc->hc_num);
  12177. +
  12178. + switch (usb_pipetype(_qtd->urb->pipe)) {
  12179. + case PIPE_CONTROL:
  12180. + case PIPE_BULK:
  12181. + _qtd->error_count++;
  12182. + if (!_hc->qh->ping_state) {
  12183. + update_urb_state_xfer_intr(_hc, _hc_regs, _qtd->urb,
  12184. + _qtd, DWC_OTG_HC_XFER_XACT_ERR);
  12185. + save_data_toggle(_hc, _hc_regs, _qtd);
  12186. + if (!_hc->ep_is_in && _qtd->urb->dev->speed == USB_SPEED_HIGH) {
  12187. + _hc->qh->ping_state = 1;
  12188. + }
  12189. + }
  12190. +
  12191. + /*
  12192. + * Halt the channel so the transfer can be re-started from
  12193. + * the appropriate point or the PING protocol will start.
  12194. + */
  12195. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_XACT_ERR, must_free);
  12196. + break;
  12197. + case PIPE_INTERRUPT:
  12198. + _qtd->error_count++;
  12199. + if ((_hc->do_split) && (_hc->complete_split)) {
  12200. + _qtd->complete_split = 0;
  12201. + }
  12202. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_XACT_ERR, must_free);
  12203. + break;
  12204. + case PIPE_ISOCHRONOUS:
  12205. + {
  12206. + dwc_otg_halt_status_e halt_status;
  12207. + halt_status = update_isoc_urb_state(_hcd, _hc, _hc_regs, _qtd,
  12208. + DWC_OTG_HC_XFER_XACT_ERR);
  12209. +
  12210. + halt_channel(_hcd, _hc, _qtd, halt_status, must_free);
  12211. + }
  12212. + break;
  12213. + }
  12214. +
  12215. +
  12216. + disable_hc_int(_hc_regs,xacterr);
  12217. +
  12218. + return 1;
  12219. +}
  12220. +
  12221. +/**
  12222. + * Handles a host channel frame overrun interrupt. This handler may be called
  12223. + * in either DMA mode or Slave mode.
  12224. + */
  12225. +static int32_t handle_hc_frmovrun_intr(dwc_otg_hcd_t *_hcd,
  12226. + dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
  12227. +{
  12228. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  12229. + "Frame Overrun--\n", _hc->hc_num);
  12230. +
  12231. + switch (usb_pipetype(_qtd->urb->pipe)) {
  12232. + case PIPE_CONTROL:
  12233. + case PIPE_BULK:
  12234. + break;
  12235. + case PIPE_INTERRUPT:
  12236. + halt_channel(_hcd, _hc, _qtd, DWC_OTG_HC_XFER_FRAME_OVERRUN, must_free);
  12237. + break;
  12238. + case PIPE_ISOCHRONOUS:
  12239. + {
  12240. + dwc_otg_halt_status_e halt_status;
  12241. + halt_status = update_isoc_urb_state(_hcd, _hc, _hc_regs, _qtd,
  12242. + DWC_OTG_HC_XFER_FRAME_OVERRUN);
  12243. +
  12244. + halt_channel(_hcd, _hc, _qtd, halt_status, must_free);
  12245. + }
  12246. + break;
  12247. + }
  12248. +
  12249. + disable_hc_int(_hc_regs,frmovrun);
  12250. +
  12251. + return 1;
  12252. +}
  12253. +
  12254. +/**
  12255. + * Handles a host channel data toggle error interrupt. This handler may be
  12256. + * called in either DMA mode or Slave mode.
  12257. + */
  12258. +static int32_t handle_hc_datatglerr_intr(dwc_otg_hcd_t *_hcd,
  12259. + dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
  12260. +{
  12261. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  12262. + "Data Toggle Error--\n", _hc->hc_num);
  12263. +
  12264. + if (_hc->ep_is_in) {
  12265. + _qtd->error_count = 0;
  12266. + } else {
  12267. + DWC_ERROR("Data Toggle Error on OUT transfer,"
  12268. + "channel %d\n", _hc->hc_num);
  12269. + }
  12270. +
  12271. + disable_hc_int(_hc_regs,datatglerr);
  12272. +
  12273. + return 1;
  12274. +}
  12275. +
  12276. +#ifdef DEBUG
  12277. +/**
  12278. + * This function is for debug only. It checks that a valid halt status is set
  12279. + * and that HCCHARn.chdis is clear. If there's a problem, corrective action is
  12280. + * taken and a warning is issued.
  12281. + * @return 1 if halt status is ok, 0 otherwise.
  12282. + */
  12283. +static inline int halt_status_ok(dwc_otg_hcd_t *_hcd,
  12284. + dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
  12285. +{
  12286. + hcchar_data_t hcchar;
  12287. + hctsiz_data_t hctsiz;
  12288. + hcint_data_t hcint;
  12289. + hcintmsk_data_t hcintmsk;
  12290. + hcsplt_data_t hcsplt;
  12291. +
  12292. + if (_hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS) {
  12293. + /*
  12294. + * This code is here only as a check. This condition should
  12295. + * never happen. Ignore the halt if it does occur.
  12296. + */
  12297. + hcchar.d32 = dwc_read_reg32(&_hc_regs->hcchar);
  12298. + hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);
  12299. + hcint.d32 = dwc_read_reg32(&_hc_regs->hcint);
  12300. + hcintmsk.d32 = dwc_read_reg32(&_hc_regs->hcintmsk);
  12301. + hcsplt.d32 = dwc_read_reg32(&_hc_regs->hcsplt);
  12302. + DWC_WARN("%s: _hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS, "
  12303. + "channel %d, hcchar 0x%08x, hctsiz 0x%08x, "
  12304. + "hcint 0x%08x, hcintmsk 0x%08x, "
  12305. + "hcsplt 0x%08x, qtd->complete_split %d\n",
  12306. + __func__, _hc->hc_num, hcchar.d32, hctsiz.d32,
  12307. + hcint.d32, hcintmsk.d32,
  12308. + hcsplt.d32, _qtd->complete_split);
  12309. +
  12310. + DWC_WARN("%s: no halt status, channel %d, ignoring interrupt\n",
  12311. + __func__, _hc->hc_num);
  12312. + DWC_WARN("\n");
  12313. + clear_hc_int(_hc_regs,chhltd);
  12314. + return 0;
  12315. + }
  12316. +
  12317. + /*
  12318. + * This code is here only as a check. hcchar.chdis should
  12319. + * never be set when the halt interrupt occurs. Halt the
  12320. + * channel again if it does occur.
  12321. + */
  12322. + hcchar.d32 = dwc_read_reg32(&_hc_regs->hcchar);
  12323. + if (hcchar.b.chdis) {
  12324. + DWC_WARN("%s: hcchar.chdis set unexpectedly, "
  12325. + "hcchar 0x%08x, trying to halt again\n",
  12326. + __func__, hcchar.d32);
  12327. + clear_hc_int(_hc_regs,chhltd);
  12328. + _hc->halt_pending = 0;
  12329. + halt_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
  12330. + return 0;
  12331. + }
  12332. +
  12333. + return 1;
  12334. +}
  12335. +#endif
  12336. +
  12337. +/**
  12338. + * Handles a host Channel Halted interrupt in DMA mode. This handler
  12339. + * determines the reason the channel halted and proceeds accordingly.
  12340. + */
  12341. +static void handle_hc_chhltd_intr_dma(dwc_otg_hcd_t *_hcd,
  12342. + dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
  12343. +{
  12344. + hcint_data_t hcint;
  12345. + hcintmsk_data_t hcintmsk;
  12346. +
  12347. + if (_hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
  12348. + _hc->halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
  12349. + /*
  12350. + * Just release the channel. A dequeue can happen on a
  12351. + * transfer timeout. In the case of an AHB Error, the channel
  12352. + * was forced to halt because there's no way to gracefully
  12353. + * recover.
  12354. + */
  12355. + release_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
  12356. + return;
  12357. + }
  12358. +
  12359. + /* Read the HCINTn register to determine the cause for the halt. */
  12360. + hcint.d32 = dwc_read_reg32(&_hc_regs->hcint);
  12361. + hcintmsk.d32 = dwc_read_reg32(&_hc_regs->hcintmsk);
  12362. +
  12363. + if (hcint.b.xfercomp) {
  12364. + /** @todo This is here because of a possible hardware bug. Spec
  12365. + * says that on SPLIT-ISOC OUT transfers in DMA mode that a HALT
  12366. + * interrupt w/ACK bit set should occur, but I only see the
  12367. + * XFERCOMP bit, even with it masked out. This is a workaround
  12368. + * for that behavior. Should fix this when hardware is fixed.
  12369. + */
  12370. + if ((_hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && (!_hc->ep_is_in)) {
  12371. + handle_hc_ack_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
  12372. + }
  12373. + handle_hc_xfercomp_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
  12374. + } else if (hcint.b.stall) {
  12375. + handle_hc_stall_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
  12376. + } else if (hcint.b.xacterr) {
  12377. + /*
  12378. + * Must handle xacterr before nak or ack. Could get a xacterr
  12379. + * at the same time as either of these on a BULK/CONTROL OUT
  12380. + * that started with a PING. The xacterr takes precedence.
  12381. + */
  12382. + handle_hc_xacterr_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
  12383. + } else if (hcint.b.nyet) {
  12384. + /*
  12385. + * Must handle nyet before nak or ack. Could get a nyet at the
  12386. + * same time as either of those on a BULK/CONTROL OUT that
  12387. + * started with a PING. The nyet takes precedence.
  12388. + */
  12389. + handle_hc_nyet_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
  12390. + } else if (hcint.b.bblerr) {
  12391. + handle_hc_babble_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
  12392. + } else if (hcint.b.frmovrun) {
  12393. + handle_hc_frmovrun_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
  12394. + } else if (hcint.b.datatglerr) {
  12395. + handle_hc_datatglerr_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
  12396. + _hc->qh->data_toggle = 0;
  12397. + halt_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
  12398. + } else if (hcint.b.nak && !hcintmsk.b.nak) {
  12399. + /*
  12400. + * If nak is not masked, it's because a non-split IN transfer
  12401. + * is in an error state. In that case, the nak is handled by
  12402. + * the nak interrupt handler, not here. Handle nak here for
  12403. + * BULK/CONTROL OUT transfers, which halt on a NAK to allow
  12404. + * rewinding the buffer pointer.
  12405. + */
  12406. + handle_hc_nak_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
  12407. + } else if (hcint.b.ack && !hcintmsk.b.ack) {
  12408. + /*
  12409. + * If ack is not masked, it's because a non-split IN transfer
  12410. + * is in an error state. In that case, the ack is handled by
  12411. + * the ack interrupt handler, not here. Handle ack here for
  12412. + * split transfers. Start splits halt on ACK.
  12413. + */
  12414. + handle_hc_ack_intr(_hcd, _hc, _hc_regs, _qtd, must_free);
  12415. + } else {
  12416. + if (_hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
  12417. + _hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
  12418. + /*
  12419. + * A periodic transfer halted with no other channel
  12420. + * interrupts set. Assume it was halted by the core
  12421. + * because it could not be completed in its scheduled
  12422. + * (micro)frame.
  12423. + */
  12424. +#ifdef DEBUG
  12425. + DWC_PRINT("%s: Halt channel %d (assume incomplete periodic transfer)\n",
  12426. + __func__, _hc->hc_num);
  12427. +#endif /* */
  12428. + halt_channel(_hcd, _hc, _qtd,
  12429. + DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE, must_free);
  12430. + } else {
  12431. +#ifdef DEBUG
  12432. + DWC_ERROR("%s: Channel %d, DMA Mode -- ChHltd set, but reason "
  12433. + "for halting is unknown, nyet %d, hcint 0x%08x, intsts 0x%08x\n",
  12434. + __func__, _hc->hc_num, hcint.b.nyet, hcint.d32,
  12435. + dwc_read_reg32(&_hcd->core_if->core_global_regs->gintsts));
  12436. +#endif
  12437. + halt_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
  12438. + }
  12439. + }
  12440. +}
  12441. +
  12442. +/**
  12443. + * Handles a host channel Channel Halted interrupt.
  12444. + *
  12445. + * In slave mode, this handler is called only when the driver specifically
  12446. + * requests a halt. This occurs during handling other host channel interrupts
  12447. + * (e.g. nak, xacterr, stall, nyet, etc.).
  12448. + *
  12449. + * In DMA mode, this is the interrupt that occurs when the core has finished
  12450. + * processing a transfer on a channel. Other host channel interrupts (except
  12451. + * ahberr) are disabled in DMA mode.
  12452. + */
  12453. +static int32_t handle_hc_chhltd_intr(dwc_otg_hcd_t *_hcd,
  12454. + dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd, int *must_free)
  12455. +{
  12456. + DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
  12457. + "Channel Halted--\n", _hc->hc_num);
  12458. +
  12459. + if (_hcd->core_if->dma_enable) {
  12460. + handle_hc_chhltd_intr_dma(_hcd, _hc, _hc_regs, _qtd, must_free);
  12461. + } else {
  12462. +#ifdef DEBUG
  12463. + if (!halt_status_ok(_hcd, _hc, _hc_regs, _qtd, must_free)) {
  12464. + return 1;
  12465. + }
  12466. +#endif /* */
  12467. + release_channel(_hcd, _hc, _qtd, _hc->halt_status, must_free);
  12468. + }
  12469. +
  12470. + return 1;
  12471. +}
  12472. +
  12473. +/** Handles interrupt for a specific Host Channel */
  12474. +int32_t dwc_otg_hcd_handle_hc_n_intr (dwc_otg_hcd_t *_dwc_otg_hcd, uint32_t _num)
  12475. +{
  12476. + int must_free = 0;
  12477. + int retval = 0;
  12478. + hcint_data_t hcint;
  12479. + hcintmsk_data_t hcintmsk;
  12480. + dwc_hc_t *hc;
  12481. + dwc_otg_hc_regs_t *hc_regs;
  12482. + dwc_otg_qtd_t *qtd;
  12483. +
  12484. + DWC_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", _num);
  12485. +
  12486. + hc = _dwc_otg_hcd->hc_ptr_array[_num];
  12487. + hc_regs = _dwc_otg_hcd->core_if->host_if->hc_regs[_num];
  12488. + qtd = list_entry(hc->qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);
  12489. +
  12490. + hcint.d32 = dwc_read_reg32(&hc_regs->hcint);
  12491. + hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk);
  12492. + DWC_DEBUGPL(DBG_HCDV, " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n",
  12493. + hcint.d32, hcintmsk.d32, (hcint.d32 & hcintmsk.d32));
  12494. + hcint.d32 = hcint.d32 & hcintmsk.d32;
  12495. +
  12496. + if (!_dwc_otg_hcd->core_if->dma_enable) {
  12497. + if ((hcint.b.chhltd) && (hcint.d32 != 0x2)) {
  12498. + hcint.b.chhltd = 0;
  12499. + }
  12500. + }
  12501. +
  12502. + if (hcint.b.xfercomp) {
  12503. + retval |= handle_hc_xfercomp_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
  12504. + /*
  12505. + * If NYET occurred at same time as Xfer Complete, the NYET is
  12506. + * handled by the Xfer Complete interrupt handler. Don't want
  12507. + * to call the NYET interrupt handler in this case.
  12508. + */
  12509. + hcint.b.nyet = 0;
  12510. + }
  12511. + if (hcint.b.chhltd) {
  12512. + retval |= handle_hc_chhltd_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
  12513. + }
  12514. + if (hcint.b.ahberr) {
  12515. + retval |= handle_hc_ahberr_intr(_dwc_otg_hcd, hc, hc_regs, qtd);
  12516. + }
  12517. + if (hcint.b.stall) {
  12518. + retval |= handle_hc_stall_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
  12519. + }
  12520. + if (hcint.b.nak) {
  12521. + retval |= handle_hc_nak_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
  12522. + }
  12523. + if (hcint.b.ack) {
  12524. + retval |= handle_hc_ack_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
  12525. + }
  12526. + if (hcint.b.nyet) {
  12527. + retval |= handle_hc_nyet_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
  12528. + }
  12529. + if (hcint.b.xacterr) {
  12530. + retval |= handle_hc_xacterr_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
  12531. + }
  12532. + if (hcint.b.bblerr) {
  12533. + retval |= handle_hc_babble_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
  12534. + }
  12535. + if (hcint.b.frmovrun) {
  12536. + retval |= handle_hc_frmovrun_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
  12537. + }
  12538. + if (hcint.b.datatglerr) {
  12539. + retval |= handle_hc_datatglerr_intr(_dwc_otg_hcd, hc, hc_regs, qtd, &must_free);
  12540. + }
  12541. +
  12542. + /*
  12543. + * Logic to free the qtd here, at the end of the hc intr
  12544. + * processing, if the handling of this interrupt determined
  12545. + * that it needs to be freed.
  12546. + */
  12547. + if (must_free) {
  12548. + /* Free the qtd here now that we are done using it. */
  12549. + dwc_otg_hcd_qtd_free(qtd);
  12550. + }
  12551. + return retval;
  12552. +}
  12553. +
  12554. +#endif /* DWC_DEVICE_ONLY */
  12555. diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c
  12556. new file mode 100644
  12557. index 0000000..fcb5ce6
  12558. --- /dev/null
  12559. +++ b/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c
  12560. @@ -0,0 +1,794 @@
  12561. +/* ==========================================================================
  12562. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd_queue.c $
  12563. + * $Revision: 1.1.1.1 $
  12564. + * $Date: 2009-04-17 06:15:34 $
  12565. + * $Change: 537387 $
  12566. + *
  12567. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  12568. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  12569. + * otherwise expressly agreed to in writing between Synopsys and you.
  12570. + *
  12571. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  12572. + * any End User Software License Agreement or Agreement for Licensed Product
  12573. + * with Synopsys or any supplement thereto. You are permitted to use and
  12574. + * redistribute this Software in source and binary forms, with or without
  12575. + * modification, provided that redistributions of source code must retain this
  12576. + * notice. You may not view, use, disclose, copy or distribute this file or
  12577. + * any information contained herein except pursuant to this license grant from
  12578. + * Synopsys. If you do not agree with this notice, including the disclaimer
  12579. + * below, then you are not authorized to use the Software.
  12580. + *
  12581. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  12582. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  12583. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  12584. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  12585. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  12586. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  12587. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12588. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12589. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  12590. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  12591. + * DAMAGE.
  12592. + * ========================================================================== */
  12593. +#ifndef DWC_DEVICE_ONLY
  12594. +
  12595. +/**
  12596. + * @file
  12597. + *
  12598. + * This file contains the functions to manage Queue Heads and Queue
  12599. + * Transfer Descriptors.
  12600. + */
  12601. +#include <linux/kernel.h>
  12602. +#include <linux/module.h>
  12603. +#include <linux/moduleparam.h>
  12604. +#include <linux/init.h>
  12605. +#include <linux/device.h>
  12606. +#include <linux/errno.h>
  12607. +#include <linux/list.h>
  12608. +#include <linux/interrupt.h>
  12609. +#include <linux/string.h>
  12610. +
  12611. +#include "dwc_otg_driver.h"
  12612. +#include "dwc_otg_hcd.h"
  12613. +#include "dwc_otg_regs.h"
  12614. +
  12615. +/**
  12616. + * This function allocates and initializes a QH.
  12617. + *
  12618. + * @param _hcd The HCD state structure for the DWC OTG controller.
  12619. + * @param[in] _urb Holds the information about the device/endpoint that we need
  12620. + * to initialize the QH.
  12621. + *
  12622. + * @return Returns pointer to the newly allocated QH, or NULL on error. */
  12623. +dwc_otg_qh_t *dwc_otg_hcd_qh_create (dwc_otg_hcd_t *_hcd, struct urb *_urb)
  12624. +{
  12625. + dwc_otg_qh_t *qh;
  12626. +
  12627. + /* Allocate memory */
  12628. + /** @todo add memflags argument */
  12629. + qh = dwc_otg_hcd_qh_alloc ();
  12630. + if (qh == NULL) {
  12631. + return NULL;
  12632. + }
  12633. +
  12634. + dwc_otg_hcd_qh_init (_hcd, qh, _urb);
  12635. + return qh;
  12636. +}
  12637. +
  12638. +/** Free each QTD in the QH's QTD-list then free the QH. QH should already be
  12639. + * removed from a list. QTD list should already be empty if called from URB
  12640. + * Dequeue.
  12641. + *
  12642. + * @param[in] _qh The QH to free.
  12643. + */
  12644. +void dwc_otg_hcd_qh_free (dwc_otg_qh_t *_qh)
  12645. +{
  12646. + dwc_otg_qtd_t *qtd;
  12647. + struct list_head *pos;
  12648. + unsigned long flags;
  12649. +
  12650. + /* Free each QTD in the QTD list */
  12651. + local_irq_save (flags);
  12652. + for (pos = _qh->qtd_list.next;
  12653. + pos != &_qh->qtd_list;
  12654. + pos = _qh->qtd_list.next)
  12655. + {
  12656. + list_del (pos);
  12657. + qtd = dwc_list_to_qtd (pos);
  12658. + dwc_otg_hcd_qtd_free (qtd);
  12659. + }
  12660. + local_irq_restore (flags);
  12661. +
  12662. + kfree (_qh);
  12663. + return;
  12664. +}
  12665. +
  12666. +/** Initializes a QH structure.
  12667. + *
  12668. + * @param[in] _hcd The HCD state structure for the DWC OTG controller.
  12669. + * @param[in] _qh The QH to init.
  12670. + * @param[in] _urb Holds the information about the device/endpoint that we need
  12671. + * to initialize the QH. */
  12672. +#define SCHEDULE_SLOP 10
  12673. +void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_urb)
  12674. +{
  12675. + memset (_qh, 0, sizeof (dwc_otg_qh_t));
  12676. +
  12677. + /* Initialize QH */
  12678. + switch (usb_pipetype(_urb->pipe)) {
  12679. + case PIPE_CONTROL:
  12680. + _qh->ep_type = USB_ENDPOINT_XFER_CONTROL;
  12681. + break;
  12682. + case PIPE_BULK:
  12683. + _qh->ep_type = USB_ENDPOINT_XFER_BULK;
  12684. + break;
  12685. + case PIPE_ISOCHRONOUS:
  12686. + _qh->ep_type = USB_ENDPOINT_XFER_ISOC;
  12687. + break;
  12688. + case PIPE_INTERRUPT:
  12689. + _qh->ep_type = USB_ENDPOINT_XFER_INT;
  12690. + break;
  12691. + }
  12692. +
  12693. + _qh->ep_is_in = usb_pipein(_urb->pipe) ? 1 : 0;
  12694. +
  12695. + _qh->data_toggle = DWC_OTG_HC_PID_DATA0;
  12696. + _qh->maxp = usb_maxpacket(_urb->dev, _urb->pipe, !(usb_pipein(_urb->pipe)));
  12697. + INIT_LIST_HEAD(&_qh->qtd_list);
  12698. + INIT_LIST_HEAD(&_qh->qh_list_entry);
  12699. + _qh->channel = NULL;
  12700. +
  12701. + /* FS/LS Enpoint on HS Hub
  12702. + * NOT virtual root hub */
  12703. + _qh->do_split = 0;
  12704. + _qh->speed = _urb->dev->speed;
  12705. + if (((_urb->dev->speed == USB_SPEED_LOW) ||
  12706. + (_urb->dev->speed == USB_SPEED_FULL)) &&
  12707. + (_urb->dev->tt) && (_urb->dev->tt->hub) && (_urb->dev->tt->hub->devnum != 1)) {
  12708. + DWC_DEBUGPL(DBG_HCD, "QH init: EP %d: TT found at hub addr %d, for port %d\n",
  12709. + usb_pipeendpoint(_urb->pipe), _urb->dev->tt->hub->devnum,
  12710. + _urb->dev->ttport);
  12711. + _qh->do_split = 1;
  12712. + }
  12713. +
  12714. + if (_qh->ep_type == USB_ENDPOINT_XFER_INT ||
  12715. + _qh->ep_type == USB_ENDPOINT_XFER_ISOC) {
  12716. + /* Compute scheduling parameters once and save them. */
  12717. + hprt0_data_t hprt;
  12718. +
  12719. + /** @todo Account for split transfers in the bus time. */
  12720. + int bytecount = dwc_hb_mult(_qh->maxp) * dwc_max_packet(_qh->maxp);
  12721. + _qh->usecs = NS_TO_US(usb_calc_bus_time(_urb->dev->speed,
  12722. + usb_pipein(_urb->pipe),
  12723. + (_qh->ep_type == USB_ENDPOINT_XFER_ISOC),bytecount));
  12724. +
  12725. + /* Start in a slightly future (micro)frame. */
  12726. + _qh->sched_frame = dwc_frame_num_inc(_hcd->frame_number, SCHEDULE_SLOP);
  12727. + _qh->interval = _urb->interval;
  12728. +#if 0
  12729. + /* Increase interrupt polling rate for debugging. */
  12730. + if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
  12731. + _qh->interval = 8;
  12732. + }
  12733. +#endif
  12734. + hprt.d32 = dwc_read_reg32(_hcd->core_if->host_if->hprt0);
  12735. + if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) &&
  12736. + ((_urb->dev->speed == USB_SPEED_LOW) ||
  12737. + (_urb->dev->speed == USB_SPEED_FULL)))
  12738. + {
  12739. + _qh->interval *= 8;
  12740. + _qh->sched_frame |= 0x7;
  12741. + _qh->start_split_frame = _qh->sched_frame;
  12742. + }
  12743. + }
  12744. +
  12745. + DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n");
  12746. + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - qh = %p\n", _qh);
  12747. + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Device Address = %d\n",
  12748. + _urb->dev->devnum);
  12749. + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Endpoint %d, %s\n",
  12750. + usb_pipeendpoint(_urb->pipe),
  12751. + usb_pipein(_urb->pipe) == USB_DIR_IN ? "IN" : "OUT");
  12752. + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Speed = %s\n",
  12753. + ({ char *speed; switch (_urb->dev->speed) {
  12754. + case USB_SPEED_LOW: speed = "low"; break;
  12755. + case USB_SPEED_FULL: speed = "full"; break;
  12756. + case USB_SPEED_HIGH: speed = "high"; break;
  12757. + default: speed = "?"; break;
  12758. + }; speed;}));
  12759. + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Type = %s\n",
  12760. + ({ char *type; switch (_qh->ep_type) {
  12761. + case USB_ENDPOINT_XFER_ISOC: type = "isochronous"; break;
  12762. + case USB_ENDPOINT_XFER_INT: type = "interrupt"; break;
  12763. + case USB_ENDPOINT_XFER_CONTROL: type = "control"; break;
  12764. + case USB_ENDPOINT_XFER_BULK: type = "bulk"; break;
  12765. + default: type = "?"; break;
  12766. + }; type;}));
  12767. +#ifdef DEBUG
  12768. + if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
  12769. + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n",
  12770. + _qh->usecs);
  12771. + DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n",
  12772. + _qh->interval);
  12773. + }
  12774. +#endif
  12775. +
  12776. + return;
  12777. +}
  12778. +
  12779. +/**
  12780. + * Microframe scheduler
  12781. + * track the total use in hcd->frame_usecs
  12782. + * keep each qh use in qh->frame_usecs
  12783. + * when surrendering the qh then donate the time back
  12784. + */
  12785. +const unsigned short max_uframe_usecs[]={ 100, 100, 100, 100, 100, 100, 30, 0 };
  12786. +
  12787. +/*
  12788. + * called from dwc_otg_hcd.c:dwc_otg_hcd_init
  12789. + */
  12790. +int init_hcd_usecs(dwc_otg_hcd_t *_hcd)
  12791. +{
  12792. + int i;
  12793. + for (i=0; i<8; i++) {
  12794. + _hcd->frame_usecs[i] = max_uframe_usecs[i];
  12795. + }
  12796. + return 0;
  12797. +}
  12798. +
  12799. +static int find_single_uframe(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh)
  12800. +{
  12801. + int i;
  12802. + unsigned short utime;
  12803. + int t_left;
  12804. + int ret;
  12805. + int done;
  12806. +
  12807. + ret = -1;
  12808. + utime = _qh->usecs;
  12809. + t_left = utime;
  12810. + i = 0;
  12811. + done = 0;
  12812. + while (done == 0) {
  12813. + /* At the start _hcd->frame_usecs[i] = max_uframe_usecs[i]; */
  12814. + if (utime <= _hcd->frame_usecs[i]) {
  12815. + _hcd->frame_usecs[i] -= utime;
  12816. + _qh->frame_usecs[i] += utime;
  12817. + t_left -= utime;
  12818. + ret = i;
  12819. + done = 1;
  12820. + return ret;
  12821. + } else {
  12822. + i++;
  12823. + if (i == 8) {
  12824. + done = 1;
  12825. + ret = -1;
  12826. + }
  12827. + }
  12828. + }
  12829. + return ret;
  12830. +}
  12831. +
  12832. +/*
  12833. + * use this for FS apps that can span multiple uframes
  12834. + */
  12835. +static int find_multi_uframe(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh)
  12836. +{
  12837. + int i;
  12838. + int j;
  12839. + unsigned short utime;
  12840. + int t_left;
  12841. + int ret;
  12842. + int done;
  12843. + unsigned short xtime;
  12844. +
  12845. + ret = -1;
  12846. + utime = _qh->usecs;
  12847. + t_left = utime;
  12848. + i = 0;
  12849. + done = 0;
  12850. +loop:
  12851. + while (done == 0) {
  12852. + if(_hcd->frame_usecs[i] <= 0) {
  12853. + i++;
  12854. + if (i == 8) {
  12855. + done = 1;
  12856. + ret = -1;
  12857. + }
  12858. + goto loop;
  12859. + }
  12860. +
  12861. + /*
  12862. + * we need n consequtive slots
  12863. + * so use j as a start slot j plus j+1 must be enough time (for now)
  12864. + */
  12865. + xtime= _hcd->frame_usecs[i];
  12866. + for (j = i+1 ; j < 8 ; j++ ) {
  12867. + /*
  12868. + * if we add this frame remaining time to xtime we may
  12869. + * be OK, if not we need to test j for a complete frame
  12870. + */
  12871. + if ((xtime+_hcd->frame_usecs[j]) < utime) {
  12872. + if (_hcd->frame_usecs[j] < max_uframe_usecs[j]) {
  12873. + j = 8;
  12874. + ret = -1;
  12875. + continue;
  12876. + }
  12877. + }
  12878. + if (xtime >= utime) {
  12879. + ret = i;
  12880. + j = 8; /* stop loop with a good value ret */
  12881. + continue;
  12882. + }
  12883. + /* add the frame time to x time */
  12884. + xtime += _hcd->frame_usecs[j];
  12885. + /* we must have a fully available next frame or break */
  12886. + if ((xtime < utime)
  12887. + && (_hcd->frame_usecs[j] == max_uframe_usecs[j])) {
  12888. + ret = -1;
  12889. + j = 8; /* stop loop with a bad value ret */
  12890. + continue;
  12891. + }
  12892. + }
  12893. + if (ret >= 0) {
  12894. + t_left = utime;
  12895. + for (j = i; (t_left>0) && (j < 8); j++ ) {
  12896. + t_left -= _hcd->frame_usecs[j];
  12897. + if ( t_left <= 0 ) {
  12898. + _qh->frame_usecs[j] += _hcd->frame_usecs[j] + t_left;
  12899. + _hcd->frame_usecs[j]= -t_left;
  12900. + ret = i;
  12901. + done = 1;
  12902. + } else {
  12903. + _qh->frame_usecs[j] += _hcd->frame_usecs[j];
  12904. + _hcd->frame_usecs[j] = 0;
  12905. + }
  12906. + }
  12907. + } else {
  12908. + i++;
  12909. + if (i == 8) {
  12910. + done = 1;
  12911. + ret = -1;
  12912. + }
  12913. + }
  12914. + }
  12915. + return ret;
  12916. +}
  12917. +
  12918. +static int find_uframe(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh)
  12919. +{
  12920. + int ret;
  12921. + ret = -1;
  12922. +
  12923. + if (_qh->speed == USB_SPEED_HIGH) {
  12924. + /* if this is a hs transaction we need a full frame */
  12925. + ret = find_single_uframe(_hcd, _qh);
  12926. + } else {
  12927. + /* if this is a fs transaction we may need a sequence of frames */
  12928. + ret = find_multi_uframe(_hcd, _qh);
  12929. + }
  12930. + return ret;
  12931. +}
  12932. +
  12933. +/**
  12934. + * Checks that the max transfer size allowed in a host channel is large enough
  12935. + * to handle the maximum data transfer in a single (micro)frame for a periodic
  12936. + * transfer.
  12937. + *
  12938. + * @param _hcd The HCD state structure for the DWC OTG controller.
  12939. + * @param _qh QH for a periodic endpoint.
  12940. + *
  12941. + * @return 0 if successful, negative error code otherwise.
  12942. + */
  12943. +static int check_max_xfer_size(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
  12944. +{
  12945. + int status;
  12946. + uint32_t max_xfer_size;
  12947. + uint32_t max_channel_xfer_size;
  12948. +
  12949. + status = 0;
  12950. +
  12951. + max_xfer_size = dwc_max_packet(_qh->maxp) * dwc_hb_mult(_qh->maxp);
  12952. + max_channel_xfer_size = _hcd->core_if->core_params->max_transfer_size;
  12953. +
  12954. + if (max_xfer_size > max_channel_xfer_size) {
  12955. + DWC_NOTICE("%s: Periodic xfer length %d > "
  12956. + "max xfer length for channel %d\n",
  12957. + __func__, max_xfer_size, max_channel_xfer_size);
  12958. + status = -ENOSPC;
  12959. + }
  12960. +
  12961. + return status;
  12962. +}
  12963. +
  12964. +/**
  12965. + * Schedules an interrupt or isochronous transfer in the periodic schedule.
  12966. + *
  12967. + * @param _hcd The HCD state structure for the DWC OTG controller.
  12968. + * @param _qh QH for the periodic transfer. The QH should already contain the
  12969. + * scheduling information.
  12970. + *
  12971. + * @return 0 if successful, negative error code otherwise.
  12972. + */
  12973. +static int schedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
  12974. +{
  12975. + int status = 0;
  12976. +
  12977. + int frame;
  12978. + status = find_uframe(_hcd, _qh);
  12979. + frame = -1;
  12980. + if (status == 0) {
  12981. + frame = 7;
  12982. + } else {
  12983. + if (status > 0 )
  12984. + frame = status-1;
  12985. + }
  12986. +
  12987. + /* Set the new frame up */
  12988. + if (frame > -1) {
  12989. + _qh->sched_frame &= ~0x7;
  12990. + _qh->sched_frame |= (frame & 7);
  12991. + }
  12992. +
  12993. + if (status != -1 )
  12994. + status = 0;
  12995. + if (status) {
  12996. + DWC_NOTICE("%s: Insufficient periodic bandwidth for "
  12997. + "periodic transfer.\n", __func__);
  12998. + return status;
  12999. + }
  13000. +
  13001. + status = check_max_xfer_size(_hcd, _qh);
  13002. + if (status) {
  13003. + DWC_NOTICE("%s: Channel max transfer size too small "
  13004. + "for periodic transfer.\n", __func__);
  13005. + return status;
  13006. + }
  13007. +
  13008. + /* Always start in the inactive schedule. */
  13009. + list_add_tail(&_qh->qh_list_entry, &_hcd->periodic_sched_inactive);
  13010. +
  13011. +
  13012. + /* Update claimed usecs per (micro)frame. */
  13013. + _hcd->periodic_usecs += _qh->usecs;
  13014. +
  13015. + /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */
  13016. + hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_allocated += _qh->usecs / _qh->interval;
  13017. + if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
  13018. + hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_int_reqs++;
  13019. + DWC_DEBUGPL(DBG_HCD, "Scheduled intr: qh %p, usecs %d, period %d\n",
  13020. + _qh, _qh->usecs, _qh->interval);
  13021. + } else {
  13022. + hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_isoc_reqs++;
  13023. + DWC_DEBUGPL(DBG_HCD, "Scheduled isoc: qh %p, usecs %d, period %d\n",
  13024. + _qh, _qh->usecs, _qh->interval);
  13025. + }
  13026. +
  13027. + return status;
  13028. +}
  13029. +
  13030. +/**
  13031. + * This function adds a QH to either the non periodic or periodic schedule if
  13032. + * it is not already in the schedule. If the QH is already in the schedule, no
  13033. + * action is taken.
  13034. + *
  13035. + * @return 0 if successful, negative error code otherwise.
  13036. + */
  13037. +int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
  13038. +{
  13039. + unsigned long flags;
  13040. + int status = 0;
  13041. +
  13042. + local_irq_save(flags);
  13043. +
  13044. + if (!list_empty(&_qh->qh_list_entry)) {
  13045. + /* QH already in a schedule. */
  13046. + goto done;
  13047. + }
  13048. +
  13049. + /* Add the new QH to the appropriate schedule */
  13050. + if (dwc_qh_is_non_per(_qh)) {
  13051. + /* Always start in the inactive schedule. */
  13052. + list_add_tail(&_qh->qh_list_entry, &_hcd->non_periodic_sched_inactive);
  13053. + } else {
  13054. + status = schedule_periodic(_hcd, _qh);
  13055. + }
  13056. +
  13057. + done:
  13058. + local_irq_restore(flags);
  13059. +
  13060. + return status;
  13061. +}
  13062. +
  13063. +/**
  13064. + * This function adds a QH to the non periodic deferred schedule.
  13065. + *
  13066. + * @return 0 if successful, negative error code otherwise.
  13067. + */
  13068. +int dwc_otg_hcd_qh_add_deferred(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh)
  13069. +{
  13070. + unsigned long flags;
  13071. + local_irq_save(flags);
  13072. + if (!list_empty(&_qh->qh_list_entry)) {
  13073. + /* QH already in a schedule. */
  13074. + goto done;
  13075. + }
  13076. +
  13077. + /* Add the new QH to the non periodic deferred schedule */
  13078. + if (dwc_qh_is_non_per(_qh)) {
  13079. + list_add_tail(&_qh->qh_list_entry,
  13080. + &_hcd->non_periodic_sched_deferred);
  13081. + }
  13082. +done:
  13083. + local_irq_restore(flags);
  13084. + return 0;
  13085. +}
  13086. +
  13087. +/**
  13088. + * Removes an interrupt or isochronous transfer from the periodic schedule.
  13089. + *
  13090. + * @param _hcd The HCD state structure for the DWC OTG controller.
  13091. + * @param _qh QH for the periodic transfer.
  13092. + */
  13093. +static void deschedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
  13094. +{
  13095. + int i;
  13096. + list_del_init(&_qh->qh_list_entry);
  13097. +
  13098. +
  13099. + /* Update claimed usecs per (micro)frame. */
  13100. + _hcd->periodic_usecs -= _qh->usecs;
  13101. +
  13102. + for (i = 0; i < 8; i++) {
  13103. + _hcd->frame_usecs[i] += _qh->frame_usecs[i];
  13104. + _qh->frame_usecs[i] = 0;
  13105. + }
  13106. + /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */
  13107. + hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_allocated -= _qh->usecs / _qh->interval;
  13108. +
  13109. + if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
  13110. + hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_int_reqs--;
  13111. + DWC_DEBUGPL(DBG_HCD, "Descheduled intr: qh %p, usecs %d, period %d\n",
  13112. + _qh, _qh->usecs, _qh->interval);
  13113. + } else {
  13114. + hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_isoc_reqs--;
  13115. + DWC_DEBUGPL(DBG_HCD, "Descheduled isoc: qh %p, usecs %d, period %d\n",
  13116. + _qh, _qh->usecs, _qh->interval);
  13117. + }
  13118. +}
  13119. +
  13120. +/**
  13121. + * Removes a QH from either the non-periodic or periodic schedule. Memory is
  13122. + * not freed.
  13123. + *
  13124. + * @param[in] _hcd The HCD state structure.
  13125. + * @param[in] _qh QH to remove from schedule. */
  13126. +void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
  13127. +{
  13128. + unsigned long flags;
  13129. +
  13130. + local_irq_save(flags);
  13131. +
  13132. + if (list_empty(&_qh->qh_list_entry)) {
  13133. + /* QH is not in a schedule. */
  13134. + goto done;
  13135. + }
  13136. +
  13137. + if (dwc_qh_is_non_per(_qh)) {
  13138. + if (_hcd->non_periodic_qh_ptr == &_qh->qh_list_entry) {
  13139. + _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
  13140. + }
  13141. + list_del_init(&_qh->qh_list_entry);
  13142. + } else {
  13143. + deschedule_periodic(_hcd, _qh);
  13144. + }
  13145. +
  13146. + done:
  13147. + local_irq_restore(flags);
  13148. +}
  13149. +
  13150. +/**
  13151. + * Defers a QH. For non-periodic QHs, removes the QH from the active
  13152. + * non-periodic schedule. The QH is added to the deferred non-periodic
  13153. + * schedule if any QTDs are still attached to the QH.
  13154. + */
  13155. +int dwc_otg_hcd_qh_deferr(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh, int delay)
  13156. +{
  13157. + int deact = 1;
  13158. + unsigned long flags;
  13159. + local_irq_save(flags);
  13160. + if (dwc_qh_is_non_per(_qh)) {
  13161. + _qh->sched_frame =
  13162. + dwc_frame_num_inc(_hcd->frame_number,
  13163. + delay);
  13164. + _qh->channel = NULL;
  13165. + _qh->qtd_in_process = NULL;
  13166. + deact = 0;
  13167. + dwc_otg_hcd_qh_remove(_hcd, _qh);
  13168. + if (!list_empty(&_qh->qtd_list)) {
  13169. + /* Add back to deferred non-periodic schedule. */
  13170. + dwc_otg_hcd_qh_add_deferred(_hcd, _qh);
  13171. + }
  13172. + }
  13173. + local_irq_restore(flags);
  13174. + return deact;
  13175. +}
  13176. +
  13177. +/**
  13178. + * Deactivates a QH. For non-periodic QHs, removes the QH from the active
  13179. + * non-periodic schedule. The QH is added to the inactive non-periodic
  13180. + * schedule if any QTDs are still attached to the QH.
  13181. + *
  13182. + * For periodic QHs, the QH is removed from the periodic queued schedule. If
  13183. + * there are any QTDs still attached to the QH, the QH is added to either the
  13184. + * periodic inactive schedule or the periodic ready schedule and its next
  13185. + * scheduled frame is calculated. The QH is placed in the ready schedule if
  13186. + * the scheduled frame has been reached already. Otherwise it's placed in the
  13187. + * inactive schedule. If there are no QTDs attached to the QH, the QH is
  13188. + * completely removed from the periodic schedule.
  13189. + */
  13190. +void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int sched_next_periodic_split)
  13191. +{
  13192. + unsigned long flags;
  13193. + local_irq_save(flags);
  13194. +
  13195. + if (dwc_qh_is_non_per(_qh)) {
  13196. + dwc_otg_hcd_qh_remove(_hcd, _qh);
  13197. + if (!list_empty(&_qh->qtd_list)) {
  13198. + /* Add back to inactive non-periodic schedule. */
  13199. + dwc_otg_hcd_qh_add(_hcd, _qh);
  13200. + }
  13201. + } else {
  13202. + uint16_t frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(_hcd));
  13203. +
  13204. + if (_qh->do_split) {
  13205. + /* Schedule the next continuing periodic split transfer */
  13206. + if (sched_next_periodic_split) {
  13207. +
  13208. + _qh->sched_frame = frame_number;
  13209. + if (dwc_frame_num_le(frame_number,
  13210. + dwc_frame_num_inc(_qh->start_split_frame, 1))) {
  13211. + /*
  13212. + * Allow one frame to elapse after start
  13213. + * split microframe before scheduling
  13214. + * complete split, but DONT if we are
  13215. + * doing the next start split in the
  13216. + * same frame for an ISOC out.
  13217. + */
  13218. + if ((_qh->ep_type != USB_ENDPOINT_XFER_ISOC) || (_qh->ep_is_in != 0)) {
  13219. + _qh->sched_frame = dwc_frame_num_inc(_qh->sched_frame, 1);
  13220. + }
  13221. + }
  13222. + } else {
  13223. + _qh->sched_frame = dwc_frame_num_inc(_qh->start_split_frame,
  13224. + _qh->interval);
  13225. + if (dwc_frame_num_le(_qh->sched_frame, frame_number)) {
  13226. + _qh->sched_frame = frame_number;
  13227. + }
  13228. + _qh->sched_frame |= 0x7;
  13229. + _qh->start_split_frame = _qh->sched_frame;
  13230. + }
  13231. + } else {
  13232. + _qh->sched_frame = dwc_frame_num_inc(_qh->sched_frame, _qh->interval);
  13233. + if (dwc_frame_num_le(_qh->sched_frame, frame_number)) {
  13234. + _qh->sched_frame = frame_number;
  13235. + }
  13236. + }
  13237. +
  13238. + if (list_empty(&_qh->qtd_list)) {
  13239. + dwc_otg_hcd_qh_remove(_hcd, _qh);
  13240. + } else {
  13241. + /*
  13242. + * Remove from periodic_sched_queued and move to
  13243. + * appropriate queue.
  13244. + */
  13245. + if (dwc_frame_num_le(_qh->sched_frame, frame_number)) {
  13246. + list_move(&_qh->qh_list_entry,
  13247. + &_hcd->periodic_sched_ready);
  13248. + } else {
  13249. + list_move(&_qh->qh_list_entry,
  13250. + &_hcd->periodic_sched_inactive);
  13251. + }
  13252. + }
  13253. + }
  13254. +
  13255. + local_irq_restore(flags);
  13256. +}
  13257. +
  13258. +/**
  13259. + * This function allocates and initializes a QTD.
  13260. + *
  13261. + * @param[in] _urb The URB to create a QTD from. Each URB-QTD pair will end up
  13262. + * pointing to each other so each pair should have a unique correlation.
  13263. + *
  13264. + * @return Returns pointer to the newly allocated QTD, or NULL on error. */
  13265. +dwc_otg_qtd_t *dwc_otg_hcd_qtd_create (struct urb *_urb)
  13266. +{
  13267. + dwc_otg_qtd_t *qtd;
  13268. +
  13269. + qtd = dwc_otg_hcd_qtd_alloc ();
  13270. + if (qtd == NULL) {
  13271. + return NULL;
  13272. + }
  13273. +
  13274. + dwc_otg_hcd_qtd_init (qtd, _urb);
  13275. + return qtd;
  13276. +}
  13277. +
  13278. +/**
  13279. + * Initializes a QTD structure.
  13280. + *
  13281. + * @param[in] _qtd The QTD to initialize.
  13282. + * @param[in] _urb The URB to use for initialization. */
  13283. +void dwc_otg_hcd_qtd_init (dwc_otg_qtd_t *_qtd, struct urb *_urb)
  13284. +{
  13285. + memset (_qtd, 0, sizeof (dwc_otg_qtd_t));
  13286. + _qtd->urb = _urb;
  13287. + if (usb_pipecontrol(_urb->pipe)) {
  13288. + /*
  13289. + * The only time the QTD data toggle is used is on the data
  13290. + * phase of control transfers. This phase always starts with
  13291. + * DATA1.
  13292. + */
  13293. + _qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
  13294. + _qtd->control_phase = DWC_OTG_CONTROL_SETUP;
  13295. + }
  13296. +
  13297. + /* start split */
  13298. + _qtd->complete_split = 0;
  13299. + _qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
  13300. + _qtd->isoc_split_offset = 0;
  13301. +
  13302. + /* Store the qtd ptr in the urb to reference what QTD. */
  13303. + _urb->hcpriv = _qtd;
  13304. + return;
  13305. +}
  13306. +
  13307. +/**
  13308. + * This function adds a QTD to the QTD-list of a QH. It will find the correct
  13309. + * QH to place the QTD into. If it does not find a QH, then it will create a
  13310. + * new QH. If the QH to which the QTD is added is not currently scheduled, it
  13311. + * is placed into the proper schedule based on its EP type.
  13312. + *
  13313. + * @param[in] _qtd The QTD to add
  13314. + * @param[in] _dwc_otg_hcd The DWC HCD structure
  13315. + *
  13316. + * @return 0 if successful, negative error code otherwise.
  13317. + */
  13318. +int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t * _qtd, dwc_otg_hcd_t * _dwc_otg_hcd)
  13319. +{
  13320. + struct usb_host_endpoint *ep;
  13321. + dwc_otg_qh_t *qh;
  13322. + unsigned long flags;
  13323. + int retval = 0;
  13324. + struct urb *urb = _qtd->urb;
  13325. +
  13326. + local_irq_save(flags);
  13327. +
  13328. + /*
  13329. + * Get the QH which holds the QTD-list to insert to. Create QH if it
  13330. + * doesn't exist.
  13331. + */
  13332. + ep = dwc_urb_to_endpoint(urb);
  13333. + qh = (dwc_otg_qh_t *)ep->hcpriv;
  13334. + if (qh == NULL) {
  13335. + qh = dwc_otg_hcd_qh_create (_dwc_otg_hcd, urb);
  13336. + if (qh == NULL) {
  13337. + retval = -1;
  13338. + goto done;
  13339. + }
  13340. + ep->hcpriv = qh;
  13341. + }
  13342. +
  13343. + _qtd->qtd_qh_ptr = qh;
  13344. + retval = dwc_otg_hcd_qh_add(_dwc_otg_hcd, qh);
  13345. + if (retval == 0) {
  13346. + list_add_tail(&_qtd->qtd_list_entry, &qh->qtd_list);
  13347. + }
  13348. +
  13349. + done:
  13350. + local_irq_restore(flags);
  13351. + return retval;
  13352. +}
  13353. +
  13354. +#endif /* DWC_DEVICE_ONLY */
  13355. diff --git a/drivers/usb/dwc_otg/dwc_otg_ifx.c b/drivers/usb/dwc_otg/dwc_otg_ifx.c
  13356. new file mode 100644
  13357. index 0000000..0a4c209
  13358. --- /dev/null
  13359. +++ b/drivers/usb/dwc_otg/dwc_otg_ifx.c
  13360. @@ -0,0 +1,100 @@
  13361. +/******************************************************************************
  13362. +**
  13363. +** FILE NAME : dwc_otg_ifx.c
  13364. +** PROJECT : Twinpass/Danube
  13365. +** MODULES : DWC OTG USB
  13366. +**
  13367. +** DATE : 12 Auguest 2007
  13368. +** AUTHOR : Sung Winder
  13369. +** DESCRIPTION : Platform specific initialization.
  13370. +** COPYRIGHT : Copyright (c) 2007
  13371. +** Infineon Technologies AG
  13372. +** 2F, No.2, Li-Hsin Rd., Hsinchu Science Park,
  13373. +** Hsin-chu City, 300 Taiwan.
  13374. +**
  13375. +** This program is free software; you can redistribute it and/or modify
  13376. +** it under the terms of the GNU General Public License as published by
  13377. +** the Free Software Foundation; either version 2 of the License, or
  13378. +** (at your option) any later version.
  13379. +**
  13380. +** HISTORY
  13381. +** $Date $Author $Comment
  13382. +** 12 Auguest 2007 Sung Winder Initiate Version
  13383. +*******************************************************************************/
  13384. +#include "dwc_otg_ifx.h"
  13385. +
  13386. +#include <linux/platform_device.h>
  13387. +#include <linux/kernel.h>
  13388. +#include <linux/ioport.h>
  13389. +#include <linux/gpio.h>
  13390. +
  13391. +#include <asm/io.h>
  13392. +//#include <asm/mach-ifxmips/ifxmips.h>
  13393. +#include <lantiq_soc.h>
  13394. +
  13395. +#define IFXMIPS_GPIO_BASE_ADDR (0xBE100B00)
  13396. +
  13397. +#define IFXMIPS_GPIO_P0_OUT ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0010))
  13398. +#define IFXMIPS_GPIO_P1_OUT ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0040))
  13399. +#define IFXMIPS_GPIO_P0_IN ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0014))
  13400. +#define IFXMIPS_GPIO_P1_IN ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0044))
  13401. +#define IFXMIPS_GPIO_P0_DIR ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0018))
  13402. +#define IFXMIPS_GPIO_P1_DIR ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0048))
  13403. +#define IFXMIPS_GPIO_P0_ALTSEL0 ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x001C))
  13404. +#define IFXMIPS_GPIO_P1_ALTSEL0 ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x004C))
  13405. +#define IFXMIPS_GPIO_P0_ALTSEL1 ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0020))
  13406. +#define IFXMIPS_GPIO_P1_ALTSEL1 ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0050))
  13407. +#define IFXMIPS_GPIO_P0_OD ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0024))
  13408. +#define IFXMIPS_GPIO_P1_OD ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0054))
  13409. +#define IFXMIPS_GPIO_P0_STOFF ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0028))
  13410. +#define IFXMIPS_GPIO_P1_STOFF ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0058))
  13411. +#define IFXMIPS_GPIO_P0_PUDSEL ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x002C))
  13412. +#define IFXMIPS_GPIO_P1_PUDSEL ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x005C))
  13413. +#define IFXMIPS_GPIO_P0_PUDEN ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0030))
  13414. +#define IFXMIPS_GPIO_P1_PUDEN ((u32 *)(IFXMIPS_GPIO_BASE_ADDR + 0x0060))
  13415. +
  13416. +
  13417. +#define writel ltq_w32
  13418. +#define readl ltq_r32
  13419. +void dwc_otg_power_on (void)
  13420. +{
  13421. + // clear power
  13422. + writel(readl(DANUBE_PMU_PWDCR) | 0x41, DANUBE_PMU_PWDCR);
  13423. + // set clock gating
  13424. + writel(readl(DANUBE_CGU_IFCCR) | 0x30, DANUBE_CGU_IFCCR);
  13425. + // set power
  13426. + writel(readl(DANUBE_PMU_PWDCR) & ~0x1, DANUBE_PMU_PWDCR);
  13427. + writel(readl(DANUBE_PMU_PWDCR) & ~0x40, DANUBE_PMU_PWDCR);
  13428. + writel(readl(DANUBE_PMU_PWDCR) & ~0x8000, DANUBE_PMU_PWDCR);
  13429. +
  13430. +#if 1//defined (DWC_HOST_ONLY)
  13431. + // make the hardware be a host controller (default)
  13432. + //clear_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_UBSCFG);
  13433. + writel(readl(DANUBE_RCU_UBSCFG) & ~(1<<DANUBE_USBCFG_HDSEL_BIT), DANUBE_RCU_UBSCFG);
  13434. +
  13435. + //#elif defined (DWC_DEVICE_ONLY)
  13436. + /* set the controller to the device mode */
  13437. + // set_bit (DANUBE_USBCFG_HDSEL_BIT, (volatile unsigned long *)DANUBE_RCU_UBSCFG);
  13438. +#else
  13439. +#error "For Danube/Twinpass, it should be HOST or Device Only."
  13440. +#endif
  13441. +
  13442. + // set the HC's byte-order to big-endian
  13443. + //set_bit (DANUBE_USBCFG_HOST_END_BIT, (volatile unsigned long *)DANUBE_RCU_UBSCFG);
  13444. + writel(readl(DANUBE_RCU_UBSCFG) | (1<<DANUBE_USBCFG_HOST_END_BIT), DANUBE_RCU_UBSCFG);
  13445. + //clear_bit (DANUBE_USBCFG_SLV_END_BIT, (volatile unsigned long *)DANUBE_RCU_UBSCFG);
  13446. + writel(readl(DANUBE_RCU_UBSCFG) & ~(1<<DANUBE_USBCFG_SLV_END_BIT), DANUBE_RCU_UBSCFG);
  13447. + //writel(0x400, DANUBE_RCU_UBSCFG);
  13448. +
  13449. + // PHY configurations.
  13450. + writel (0x14014, (volatile unsigned long *)0xbe10103c);
  13451. +}
  13452. +
  13453. +int ifx_usb_hc_init(unsigned long base_addr, int irq)
  13454. +{
  13455. + return 0;
  13456. +}
  13457. +
  13458. +void ifx_usb_hc_remove(void)
  13459. +{
  13460. +}
  13461. diff --git a/drivers/usb/dwc_otg/dwc_otg_ifx.h b/drivers/usb/dwc_otg/dwc_otg_ifx.h
  13462. new file mode 100644
  13463. index 0000000..402d7a6
  13464. --- /dev/null
  13465. +++ b/drivers/usb/dwc_otg/dwc_otg_ifx.h
  13466. @@ -0,0 +1,85 @@
  13467. +/******************************************************************************
  13468. +**
  13469. +** FILE NAME : dwc_otg_ifx.h
  13470. +** PROJECT : Twinpass/Danube
  13471. +** MODULES : DWC OTG USB
  13472. +**
  13473. +** DATE : 12 April 2007
  13474. +** AUTHOR : Sung Winder
  13475. +** DESCRIPTION : Platform specific initialization.
  13476. +** COPYRIGHT : Copyright (c) 2007
  13477. +** Infineon Technologies AG
  13478. +** 2F, No.2, Li-Hsin Rd., Hsinchu Science Park,
  13479. +** Hsin-chu City, 300 Taiwan.
  13480. +**
  13481. +** This program is free software; you can redistribute it and/or modify
  13482. +** it under the terms of the GNU General Public License as published by
  13483. +** the Free Software Foundation; either version 2 of the License, or
  13484. +** (at your option) any later version.
  13485. +**
  13486. +** HISTORY
  13487. +** $Date $Author $Comment
  13488. +** 12 April 2007 Sung Winder Initiate Version
  13489. +*******************************************************************************/
  13490. +#if !defined(__DWC_OTG_IFX_H__)
  13491. +#define __DWC_OTG_IFX_H__
  13492. +
  13493. +#include <linux/irq.h>
  13494. +#include <irq.h>
  13495. +
  13496. +// 20070316, winder added.
  13497. +#ifndef SZ_256K
  13498. +#define SZ_256K 0x00040000
  13499. +#endif
  13500. +
  13501. +extern void dwc_otg_power_on (void);
  13502. +
  13503. +/* FIXME: The current Linux-2.6 do not have these header files, but anyway, we need these. */
  13504. +// #include <asm/danube/danube.h>
  13505. +// #include <asm/ifx/irq.h>
  13506. +
  13507. +/* winder, I used the Danube parameter as default. *
  13508. + * We could change this through module param. */
  13509. +#define IFX_USB_IOMEM_BASE 0x1e101000
  13510. +#define IFX_USB_IOMEM_SIZE SZ_256K
  13511. +#define IFX_USB_IRQ LTQ_USB_INT
  13512. +
  13513. +/**
  13514. + * This function is called to set correct clock gating and power.
  13515. + * For Twinpass/Danube board.
  13516. + */
  13517. +#ifndef DANUBE_RCU_BASE_ADDR
  13518. +#define DANUBE_RCU_BASE_ADDR (0xBF203000)
  13519. +#endif
  13520. +
  13521. +#ifndef DANUBE_CGU
  13522. +#define DANUBE_CGU (0xBF103000)
  13523. +#endif
  13524. +#ifndef DANUBE_CGU_IFCCR
  13525. +/***CGU Interface Clock Control Register***/
  13526. +#define DANUBE_CGU_IFCCR ((volatile u32*)(DANUBE_CGU+ 0x0018))
  13527. +#endif
  13528. +
  13529. +#ifndef DANUBE_PMU
  13530. +#define DANUBE_PMU (KSEG1+0x1F102000)
  13531. +#endif
  13532. +#ifndef DANUBE_PMU_PWDCR
  13533. +/* PMU Power down Control Register */
  13534. +#define DANUBE_PMU_PWDCR ((volatile u32*)(DANUBE_PMU+0x001C))
  13535. +#endif
  13536. +
  13537. +
  13538. +#define DANUBE_RCU_UBSCFG ((volatile u32*)(DANUBE_RCU_BASE_ADDR + 0x18))
  13539. +#define DANUBE_USBCFG_HDSEL_BIT 11 // 0:host, 1:device
  13540. +#define DANUBE_USBCFG_HOST_END_BIT 10 // 0:little_end, 1:big_end
  13541. +#define DANUBE_USBCFG_SLV_END_BIT 9 // 0:little_end, 1:big_end
  13542. +
  13543. +extern void ltq_mask_and_ack_irq(struct irq_data *d);
  13544. +
  13545. +static void inline mask_and_ack_ifx_irq(int x)
  13546. +{
  13547. + struct irq_data d;
  13548. + d.irq = x;
  13549. + ltq_mask_and_ack_irq(&d);
  13550. +}
  13551. +#endif //__DWC_OTG_IFX_H__
  13552. diff --git a/drivers/usb/dwc_otg/dwc_otg_plat.h b/drivers/usb/dwc_otg/dwc_otg_plat.h
  13553. new file mode 100644
  13554. index 0000000..727d0c4
  13555. --- /dev/null
  13556. +++ b/drivers/usb/dwc_otg/dwc_otg_plat.h
  13557. @@ -0,0 +1,269 @@
  13558. +/* ==========================================================================
  13559. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/platform/dwc_otg_plat.h $
  13560. + * $Revision: 1.1.1.1 $
  13561. + * $Date: 2009-04-17 06:15:34 $
  13562. + * $Change: 510301 $
  13563. + *
  13564. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  13565. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  13566. + * otherwise expressly agreed to in writing between Synopsys and you.
  13567. + *
  13568. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  13569. + * any End User Software License Agreement or Agreement for Licensed Product
  13570. + * with Synopsys or any supplement thereto. You are permitted to use and
  13571. + * redistribute this Software in source and binary forms, with or without
  13572. + * modification, provided that redistributions of source code must retain this
  13573. + * notice. You may not view, use, disclose, copy or distribute this file or
  13574. + * any information contained herein except pursuant to this license grant from
  13575. + * Synopsys. If you do not agree with this notice, including the disclaimer
  13576. + * below, then you are not authorized to use the Software.
  13577. + *
  13578. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  13579. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  13580. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  13581. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  13582. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  13583. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  13584. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13585. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13586. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  13587. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  13588. + * DAMAGE.
  13589. + * ========================================================================== */
  13590. +
  13591. +#if !defined(__DWC_OTG_PLAT_H__)
  13592. +#define __DWC_OTG_PLAT_H__
  13593. +
  13594. +#include <linux/types.h>
  13595. +#include <linux/slab.h>
  13596. +#include <linux/list.h>
  13597. +#include <linux/delay.h>
  13598. +#include <asm/io.h>
  13599. +
  13600. +/**
  13601. + * @file
  13602. + *
  13603. + * This file contains the Platform Specific constants, interfaces
  13604. + * (functions and macros) for Linux.
  13605. + *
  13606. + */
  13607. +/*#if !defined(__LINUX__)
  13608. +#error "The contents of this file is Linux specific!!!"
  13609. +#endif
  13610. +*/
  13611. +#include <lantiq_soc.h>
  13612. +#define writel ltq_w32
  13613. +#define readl ltq_r32
  13614. +
  13615. +/**
  13616. + * Reads the content of a register.
  13617. + *
  13618. + * @param _reg address of register to read.
  13619. + * @return contents of the register.
  13620. + *
  13621. +
  13622. + * Usage:<br>
  13623. + * <code>uint32_t dev_ctl = dwc_read_reg32(&dev_regs->dctl);</code>
  13624. + */
  13625. +static __inline__ uint32_t dwc_read_reg32( volatile uint32_t *_reg)
  13626. +{
  13627. + return readl(_reg);
  13628. +};
  13629. +
  13630. +/**
  13631. + * Writes a register with a 32 bit value.
  13632. + *
  13633. + * @param _reg address of register to read.
  13634. + * @param _value to write to _reg.
  13635. + *
  13636. + * Usage:<br>
  13637. + * <code>dwc_write_reg32(&dev_regs->dctl, 0); </code>
  13638. + */
  13639. +static __inline__ void dwc_write_reg32( volatile uint32_t *_reg, const uint32_t _value)
  13640. +{
  13641. + writel( _value, _reg );
  13642. +};
  13643. +
  13644. +/**
  13645. + * This function modifies bit values in a register. Using the
  13646. + * algorithm: (reg_contents & ~clear_mask) | set_mask.
  13647. + *
  13648. + * @param _reg address of register to read.
  13649. + * @param _clear_mask bit mask to be cleared.
  13650. + * @param _set_mask bit mask to be set.
  13651. + *
  13652. + * Usage:<br>
  13653. + * <code> // Clear the SOF Interrupt Mask bit and <br>
  13654. + * // set the OTG Interrupt mask bit, leaving all others as they were.
  13655. + * dwc_modify_reg32(&dev_regs->gintmsk, DWC_SOF_INT, DWC_OTG_INT);</code>
  13656. + */
  13657. +static __inline__
  13658. + void dwc_modify_reg32( volatile uint32_t *_reg, const uint32_t _clear_mask, const uint32_t _set_mask)
  13659. +{
  13660. + writel( (readl(_reg) & ~_clear_mask) | _set_mask, _reg );
  13661. +};
  13662. +
  13663. +
  13664. +/**
  13665. + * Wrapper for the OS micro-second delay function.
  13666. + * @param[in] _usecs Microseconds of delay
  13667. + */
  13668. +static __inline__ void UDELAY( const uint32_t _usecs )
  13669. +{
  13670. + udelay( _usecs );
  13671. +}
  13672. +
  13673. +/**
  13674. + * Wrapper for the OS milli-second delay function.
  13675. + * @param[in] _msecs milliseconds of delay
  13676. + */
  13677. +static __inline__ void MDELAY( const uint32_t _msecs )
  13678. +{
  13679. + mdelay( _msecs );
  13680. +}
  13681. +
  13682. +/**
  13683. + * Wrapper for the Linux spin_lock. On the ARM (Integrator)
  13684. + * spin_lock() is a nop.
  13685. + *
  13686. + * @param _lock Pointer to the spinlock.
  13687. + */
  13688. +static __inline__ void SPIN_LOCK( spinlock_t *_lock )
  13689. +{
  13690. + spin_lock(_lock);
  13691. +}
  13692. +
  13693. +/**
  13694. + * Wrapper for the Linux spin_unlock. On the ARM (Integrator)
  13695. + * spin_lock() is a nop.
  13696. + *
  13697. + * @param _lock Pointer to the spinlock.
  13698. + */
  13699. +static __inline__ void SPIN_UNLOCK( spinlock_t *_lock )
  13700. +{
  13701. + spin_unlock(_lock);
  13702. +}
  13703. +
  13704. +/**
  13705. + * Wrapper (macro) for the Linux spin_lock_irqsave. On the ARM
  13706. + * (Integrator) spin_lock() is a nop.
  13707. + *
  13708. + * @param _l Pointer to the spinlock.
  13709. + * @param _f unsigned long for irq flags storage.
  13710. + */
  13711. +#define SPIN_LOCK_IRQSAVE( _l, _f ) { \
  13712. + spin_lock_irqsave(_l,_f); \
  13713. + }
  13714. +
  13715. +/**
  13716. + * Wrapper (macro) for the Linux spin_unlock_irqrestore. On the ARM
  13717. + * (Integrator) spin_lock() is a nop.
  13718. + *
  13719. + * @param _l Pointer to the spinlock.
  13720. + * @param _f unsigned long for irq flags storage.
  13721. + */
  13722. +#define SPIN_UNLOCK_IRQRESTORE( _l,_f ) {\
  13723. + spin_unlock_irqrestore(_l,_f); \
  13724. + }
  13725. +
  13726. +
  13727. +/*
  13728. + * Debugging support vanishes in non-debug builds.
  13729. + */
  13730. +
  13731. +
  13732. +/**
  13733. + * The Debug Level bit-mask variable.
  13734. + */
  13735. +extern uint32_t g_dbg_lvl;
  13736. +/**
  13737. + * Set the Debug Level variable.
  13738. + */
  13739. +static inline uint32_t SET_DEBUG_LEVEL( const uint32_t _new )
  13740. +{
  13741. + uint32_t old = g_dbg_lvl;
  13742. + g_dbg_lvl = _new;
  13743. + return old;
  13744. +}
  13745. +
  13746. +/** When debug level has the DBG_CIL bit set, display CIL Debug messages. */
  13747. +#define DBG_CIL (0x2)
  13748. +/** When debug level has the DBG_CILV bit set, display CIL Verbose debug
  13749. + * messages */
  13750. +#define DBG_CILV (0x20)
  13751. +/** When debug level has the DBG_PCD bit set, display PCD (Device) debug
  13752. + * messages */
  13753. +#define DBG_PCD (0x4)
  13754. +/** When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug
  13755. + * messages */
  13756. +#define DBG_PCDV (0x40)
  13757. +/** When debug level has the DBG_HCD bit set, display Host debug messages */
  13758. +#define DBG_HCD (0x8)
  13759. +/** When debug level has the DBG_HCDV bit set, display Verbose Host debug
  13760. + * messages */
  13761. +#define DBG_HCDV (0x80)
  13762. +/** When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host
  13763. + * mode. */
  13764. +#define DBG_HCD_URB (0x800)
  13765. +
  13766. +/** When debug level has any bit set, display debug messages */
  13767. +#define DBG_ANY (0xFF)
  13768. +
  13769. +/** All debug messages off */
  13770. +#define DBG_OFF 0
  13771. +
  13772. +/** Prefix string for DWC_DEBUG print macros. */
  13773. +#define USB_DWC "DWC_otg: "
  13774. +
  13775. +/**
  13776. + * Print a debug message when the Global debug level variable contains
  13777. + * the bit defined in <code>lvl</code>.
  13778. + *
  13779. + * @param[in] lvl - Debug level, use one of the DBG_ constants above.
  13780. + * @param[in] x - like printf
  13781. + *
  13782. + * Example:<p>
  13783. + * <code>
  13784. + * DWC_DEBUGPL( DBG_ANY, "%s(%p)\n", __func__, _reg_base_addr);
  13785. + * </code>
  13786. + * <br>
  13787. + * results in:<br>
  13788. + * <code>
  13789. + * usb-DWC_otg: dwc_otg_cil_init(ca867000)
  13790. + * </code>
  13791. + */
  13792. +#ifdef DEBUG
  13793. +
  13794. +# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)printk( KERN_DEBUG USB_DWC x ); }while(0)
  13795. +# define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x )
  13796. +
  13797. +# define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl)
  13798. +
  13799. +#else
  13800. +
  13801. +# define DWC_DEBUGPL(lvl, x...) do{}while(0)
  13802. +# define DWC_DEBUGP(x...)
  13803. +
  13804. +# define CHK_DEBUG_LEVEL(level) (0)
  13805. +
  13806. +#endif /*DEBUG*/
  13807. +
  13808. +/**
  13809. + * Print an Error message.
  13810. + */
  13811. +#define DWC_ERROR(x...) printk( KERN_ERR USB_DWC x )
  13812. +/**
  13813. + * Print a Warning message.
  13814. + */
  13815. +#define DWC_WARN(x...) printk( KERN_WARNING USB_DWC x )
  13816. +/**
  13817. + * Print a notice (normal but significant message).
  13818. + */
  13819. +#define DWC_NOTICE(x...) printk( KERN_NOTICE USB_DWC x )
  13820. +/**
  13821. + * Basic message printing.
  13822. + */
  13823. +#define DWC_PRINT(x...) printk( KERN_INFO USB_DWC x )
  13824. +
  13825. +#endif
  13826. +
  13827. diff --git a/drivers/usb/dwc_otg/dwc_otg_regs.h b/drivers/usb/dwc_otg/dwc_otg_regs.h
  13828. new file mode 100644
  13829. index 0000000..397a954
  13830. --- /dev/null
  13831. +++ b/drivers/usb/dwc_otg/dwc_otg_regs.h
  13832. @@ -0,0 +1,1797 @@
  13833. +/* ==========================================================================
  13834. + * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_regs.h $
  13835. + * $Revision: 1.1.1.1 $
  13836. + * $Date: 2009-04-17 06:15:34 $
  13837. + * $Change: 631780 $
  13838. + *
  13839. + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
  13840. + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
  13841. + * otherwise expressly agreed to in writing between Synopsys and you.
  13842. + *
  13843. + * The Software IS NOT an item of Licensed Software or Licensed Product under
  13844. + * any End User Software License Agreement or Agreement for Licensed Product
  13845. + * with Synopsys or any supplement thereto. You are permitted to use and
  13846. + * redistribute this Software in source and binary forms, with or without
  13847. + * modification, provided that redistributions of source code must retain this
  13848. + * notice. You may not view, use, disclose, copy or distribute this file or
  13849. + * any information contained herein except pursuant to this license grant from
  13850. + * Synopsys. If you do not agree with this notice, including the disclaimer
  13851. + * below, then you are not authorized to use the Software.
  13852. + *
  13853. + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
  13854. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  13855. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  13856. + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
  13857. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  13858. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  13859. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13860. + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13861. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  13862. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  13863. + * DAMAGE.
  13864. + * ========================================================================== */
  13865. +
  13866. +#ifndef __DWC_OTG_REGS_H__
  13867. +#define __DWC_OTG_REGS_H__
  13868. +
  13869. +/**
  13870. + * @file
  13871. + *
  13872. + * This file contains the data structures for accessing the DWC_otg core registers.
  13873. + *
  13874. + * The application interfaces with the HS OTG core by reading from and
  13875. + * writing to the Control and Status Register (CSR) space through the
  13876. + * AHB Slave interface. These registers are 32 bits wide, and the
  13877. + * addresses are 32-bit-block aligned.
  13878. + * CSRs are classified as follows:
  13879. + * - Core Global Registers
  13880. + * - Device Mode Registers
  13881. + * - Device Global Registers
  13882. + * - Device Endpoint Specific Registers
  13883. + * - Host Mode Registers
  13884. + * - Host Global Registers
  13885. + * - Host Port CSRs
  13886. + * - Host Channel Specific Registers
  13887. + *
  13888. + * Only the Core Global registers can be accessed in both Device and
  13889. + * Host modes. When the HS OTG core is operating in one mode, either
  13890. + * Device or Host, the application must not access registers from the
  13891. + * other mode. When the core switches from one mode to another, the
  13892. + * registers in the new mode of operation must be reprogrammed as they
  13893. + * would be after a power-on reset.
  13894. + */
  13895. +
  13896. +/****************************************************************************/
  13897. +/** DWC_otg Core registers .
  13898. + * The dwc_otg_core_global_regs structure defines the size
  13899. + * and relative field offsets for the Core Global registers.
  13900. + */
  13901. +typedef struct dwc_otg_core_global_regs
  13902. +{
  13903. + /** OTG Control and Status Register. <i>Offset: 000h</i> */
  13904. + volatile uint32_t gotgctl;
  13905. + /** OTG Interrupt Register. <i>Offset: 004h</i> */
  13906. + volatile uint32_t gotgint;
  13907. + /**Core AHB Configuration Register. <i>Offset: 008h</i> */
  13908. + volatile uint32_t gahbcfg;
  13909. +#define DWC_GLBINTRMASK 0x0001
  13910. +#define DWC_DMAENABLE 0x0020
  13911. +#define DWC_NPTXEMPTYLVL_EMPTY 0x0080
  13912. +#define DWC_NPTXEMPTYLVL_HALFEMPTY 0x0000
  13913. +#define DWC_PTXEMPTYLVL_EMPTY 0x0100
  13914. +#define DWC_PTXEMPTYLVL_HALFEMPTY 0x0000
  13915. +
  13916. +
  13917. + /**Core USB Configuration Register. <i>Offset: 00Ch</i> */
  13918. + volatile uint32_t gusbcfg;
  13919. + /**Core Reset Register. <i>Offset: 010h</i> */
  13920. + volatile uint32_t grstctl;
  13921. + /**Core Interrupt Register. <i>Offset: 014h</i> */
  13922. + volatile uint32_t gintsts;
  13923. + /**Core Interrupt Mask Register. <i>Offset: 018h</i> */
  13924. + volatile uint32_t gintmsk;
  13925. + /**Receive Status Queue Read Register (Read Only). <i>Offset: 01Ch</i> */
  13926. + volatile uint32_t grxstsr;
  13927. + /**Receive Status Queue Read & POP Register (Read Only). <i>Offset: 020h</i>*/
  13928. + volatile uint32_t grxstsp;
  13929. + /**Receive FIFO Size Register. <i>Offset: 024h</i> */
  13930. + volatile uint32_t grxfsiz;
  13931. + /**Non Periodic Transmit FIFO Size Register. <i>Offset: 028h</i> */
  13932. + volatile uint32_t gnptxfsiz;
  13933. + /**Non Periodic Transmit FIFO/Queue Status Register (Read
  13934. + * Only). <i>Offset: 02Ch</i> */
  13935. + volatile uint32_t gnptxsts;
  13936. + /**I2C Access Register. <i>Offset: 030h</i> */
  13937. + volatile uint32_t gi2cctl;
  13938. + /**PHY Vendor Control Register. <i>Offset: 034h</i> */
  13939. + volatile uint32_t gpvndctl;
  13940. + /**General Purpose Input/Output Register. <i>Offset: 038h</i> */
  13941. + volatile uint32_t ggpio;
  13942. + /**User ID Register. <i>Offset: 03Ch</i> */
  13943. + volatile uint32_t guid;
  13944. + /**Synopsys ID Register (Read Only). <i>Offset: 040h</i> */
  13945. + volatile uint32_t gsnpsid;
  13946. + /**User HW Config1 Register (Read Only). <i>Offset: 044h</i> */
  13947. + volatile uint32_t ghwcfg1;
  13948. + /**User HW Config2 Register (Read Only). <i>Offset: 048h</i> */
  13949. + volatile uint32_t ghwcfg2;
  13950. +#define DWC_SLAVE_ONLY_ARCH 0
  13951. +#define DWC_EXT_DMA_ARCH 1
  13952. +#define DWC_INT_DMA_ARCH 2
  13953. +
  13954. +#define DWC_MODE_HNP_SRP_CAPABLE 0
  13955. +#define DWC_MODE_SRP_ONLY_CAPABLE 1
  13956. +#define DWC_MODE_NO_HNP_SRP_CAPABLE 2
  13957. +#define DWC_MODE_SRP_CAPABLE_DEVICE 3
  13958. +#define DWC_MODE_NO_SRP_CAPABLE_DEVICE 4
  13959. +#define DWC_MODE_SRP_CAPABLE_HOST 5
  13960. +#define DWC_MODE_NO_SRP_CAPABLE_HOST 6
  13961. +
  13962. + /**User HW Config3 Register (Read Only). <i>Offset: 04Ch</i> */
  13963. + volatile uint32_t ghwcfg3;
  13964. + /**User HW Config4 Register (Read Only). <i>Offset: 050h</i>*/
  13965. + volatile uint32_t ghwcfg4;
  13966. + /** Reserved <i>Offset: 054h-0FFh</i> */
  13967. + uint32_t reserved[43];
  13968. + /** Host Periodic Transmit FIFO Size Register. <i>Offset: 100h</i> */
  13969. + volatile uint32_t hptxfsiz;
  13970. + /** Device Periodic Transmit FIFO#n Register if dedicated fifos are disabled,
  13971. + otherwise Device Transmit FIFO#n Register.
  13972. + * <i>Offset: 104h + (FIFO_Number-1)*04h, 1 <= FIFO Number <= 15 (1<=n<=15).</i> */
  13973. + //volatile uint32_t dptxfsiz[15];
  13974. + volatile uint32_t dptxfsiz_dieptxf[15];
  13975. +} dwc_otg_core_global_regs_t;
  13976. +
  13977. +/**
  13978. + * This union represents the bit fields of the Core OTG Control
  13979. + * and Status Register (GOTGCTL). Set the bits using the bit
  13980. + * fields then write the <i>d32</i> value to the register.
  13981. + */
  13982. +typedef union gotgctl_data
  13983. +{
  13984. + /** raw register data */
  13985. + uint32_t d32;
  13986. + /** register bits */
  13987. + struct
  13988. + {
  13989. + unsigned reserved31_21 : 11;
  13990. + unsigned currmod : 1;
  13991. + unsigned bsesvld : 1;
  13992. + unsigned asesvld : 1;
  13993. + unsigned reserved17 : 1;
  13994. + unsigned conidsts : 1;
  13995. + unsigned reserved15_12 : 4;
  13996. + unsigned devhnpen : 1;
  13997. + unsigned hstsethnpen : 1;
  13998. + unsigned hnpreq : 1;
  13999. + unsigned hstnegscs : 1;
  14000. + unsigned reserved7_2 : 6;
  14001. + unsigned sesreq : 1;
  14002. + unsigned sesreqscs : 1;
  14003. + } b;
  14004. +} gotgctl_data_t;
  14005. +
  14006. +/**
  14007. + * This union represents the bit fields of the Core OTG Interrupt Register
  14008. + * (GOTGINT). Set/clear the bits using the bit fields then write the <i>d32</i>
  14009. + * value to the register.
  14010. + */
  14011. +typedef union gotgint_data
  14012. +{
  14013. + /** raw register data */
  14014. + uint32_t d32;
  14015. + /** register bits */
  14016. + struct
  14017. + {
  14018. + /** Current Mode */
  14019. + unsigned reserved31_20 : 12;
  14020. + /** Debounce Done */
  14021. + unsigned debdone : 1;
  14022. + /** A-Device Timeout Change */
  14023. + unsigned adevtoutchng : 1;
  14024. + /** Host Negotiation Detected */
  14025. + unsigned hstnegdet : 1;
  14026. + unsigned reserver16_10 : 7;
  14027. + /** Host Negotiation Success Status Change */
  14028. + unsigned hstnegsucstschng : 1;
  14029. + /** Session Request Success Status Change */
  14030. + unsigned sesreqsucstschng : 1;
  14031. + unsigned reserved3_7 : 5;
  14032. + /** Session End Detected */
  14033. + unsigned sesenddet : 1;
  14034. + /** Current Mode */
  14035. + unsigned reserved1_0 : 2;
  14036. + } b;
  14037. +} gotgint_data_t;
  14038. +
  14039. +
  14040. +/**
  14041. + * This union represents the bit fields of the Core AHB Configuration
  14042. + * Register (GAHBCFG). Set/clear the bits using the bit fields then
  14043. + * write the <i>d32</i> value to the register.
  14044. + */
  14045. +typedef union gahbcfg_data
  14046. +{
  14047. + /** raw register data */
  14048. + uint32_t d32;
  14049. + /** register bits */
  14050. + struct
  14051. + {
  14052. +#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY 1
  14053. +#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
  14054. + unsigned reserved9_31 : 23;
  14055. + unsigned ptxfemplvl : 1;
  14056. + unsigned nptxfemplvl_txfemplvl : 1;
  14057. +#define DWC_GAHBCFG_DMAENABLE 1
  14058. + unsigned reserved : 1;
  14059. + unsigned dmaenable : 1;
  14060. +#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE 0
  14061. +#define DWC_GAHBCFG_INT_DMA_BURST_INCR 1
  14062. +#define DWC_GAHBCFG_INT_DMA_BURST_INCR4 3
  14063. +#define DWC_GAHBCFG_INT_DMA_BURST_INCR8 5
  14064. +#define DWC_GAHBCFG_INT_DMA_BURST_INCR16 7
  14065. + unsigned hburstlen : 4;
  14066. + unsigned glblintrmsk : 1;
  14067. +#define DWC_GAHBCFG_GLBINT_ENABLE 1
  14068. +
  14069. + } b;
  14070. +} gahbcfg_data_t;
  14071. +
  14072. +/**
  14073. + * This union represents the bit fields of the Core USB Configuration
  14074. + * Register (GUSBCFG). Set the bits using the bit fields then write
  14075. + * the <i>d32</i> value to the register.
  14076. + */
  14077. +typedef union gusbcfg_data
  14078. +{
  14079. + /** raw register data */
  14080. + uint32_t d32;
  14081. + /** register bits */
  14082. + struct
  14083. + {
  14084. + unsigned corrupt_tx_packet: 1; /*fscz*/
  14085. + unsigned force_device_mode: 1;
  14086. + unsigned force_host_mode: 1;
  14087. + unsigned reserved23_28 : 6;
  14088. + unsigned term_sel_dl_pulse : 1;
  14089. + unsigned ulpi_int_vbus_indicator : 1;
  14090. + unsigned ulpi_ext_vbus_drv : 1;
  14091. + unsigned ulpi_clk_sus_m : 1;
  14092. + unsigned ulpi_auto_res : 1;
  14093. + unsigned ulpi_fsls : 1;
  14094. + unsigned otgutmifssel : 1;
  14095. + unsigned phylpwrclksel : 1;
  14096. + unsigned nptxfrwnden : 1;
  14097. + unsigned usbtrdtim : 4;
  14098. + unsigned hnpcap : 1;
  14099. + unsigned srpcap : 1;
  14100. + unsigned ddrsel : 1;
  14101. + unsigned physel : 1;
  14102. + unsigned fsintf : 1;
  14103. + unsigned ulpi_utmi_sel : 1;
  14104. + unsigned phyif : 1;
  14105. + unsigned toutcal : 3;
  14106. + } b;
  14107. +} gusbcfg_data_t;
  14108. +
  14109. +/**
  14110. + * This union represents the bit fields of the Core Reset Register
  14111. + * (GRSTCTL). Set/clear the bits using the bit fields then write the
  14112. + * <i>d32</i> value to the register.
  14113. + */
  14114. +typedef union grstctl_data
  14115. +{
  14116. + /** raw register data */
  14117. + uint32_t d32;
  14118. + /** register bits */
  14119. + struct
  14120. + {
  14121. + /** AHB Master Idle. Indicates the AHB Master State
  14122. + * Machine is in IDLE condition. */
  14123. + unsigned ahbidle : 1;
  14124. + /** DMA Request Signal. Indicated DMA request is in
  14125. + * probress. Used for debug purpose. */
  14126. + unsigned dmareq : 1;
  14127. + /** Reserved */
  14128. + unsigned reserved29_11 : 19;
  14129. + /** TxFIFO Number (TxFNum) (Device and Host).
  14130. + *
  14131. + * This is the FIFO number which needs to be flushed,
  14132. + * using the TxFIFO Flush bit. This field should not
  14133. + * be changed until the TxFIFO Flush bit is cleared by
  14134. + * the core.
  14135. + * - 0x0 : Non Periodic TxFIFO Flush
  14136. + * - 0x1 : Periodic TxFIFO #1 Flush in device mode
  14137. + * or Periodic TxFIFO in host mode
  14138. + * - 0x2 : Periodic TxFIFO #2 Flush in device mode.
  14139. + * - ...
  14140. + * - 0xF : Periodic TxFIFO #15 Flush in device mode
  14141. + * - 0x10: Flush all the Transmit NonPeriodic and
  14142. + * Transmit Periodic FIFOs in the core
  14143. + */
  14144. + unsigned txfnum : 5;
  14145. + /** TxFIFO Flush (TxFFlsh) (Device and Host).
  14146. + *
  14147. + * This bit is used to selectively flush a single or
  14148. + * all transmit FIFOs. The application must first
  14149. + * ensure that the core is not in the middle of a
  14150. + * transaction. <p>The application should write into
  14151. + * this bit, only after making sure that neither the
  14152. + * DMA engine is writing into the TxFIFO nor the MAC
  14153. + * is reading the data out of the FIFO. <p>The
  14154. + * application should wait until the core clears this
  14155. + * bit, before performing any operations. This bit
  14156. + * will takes 8 clocks (slowest of PHY or AHB clock)
  14157. + * to clear.
  14158. + */
  14159. + unsigned txfflsh : 1;
  14160. + /** RxFIFO Flush (RxFFlsh) (Device and Host)
  14161. + *
  14162. + * The application can flush the entire Receive FIFO
  14163. + * using this bit. <p>The application must first
  14164. + * ensure that the core is not in the middle of a
  14165. + * transaction. <p>The application should write into
  14166. + * this bit, only after making sure that neither the
  14167. + * DMA engine is reading from the RxFIFO nor the MAC
  14168. + * is writing the data in to the FIFO. <p>The
  14169. + * application should wait until the bit is cleared
  14170. + * before performing any other operations. This bit
  14171. + * will takes 8 clocks (slowest of PHY or AHB clock)
  14172. + * to clear.
  14173. + */
  14174. + unsigned rxfflsh : 1;
  14175. + /** In Token Sequence Learning Queue Flush
  14176. + * (INTknQFlsh) (Device Only)
  14177. + */
  14178. + unsigned intknqflsh : 1;
  14179. + /** Host Frame Counter Reset (Host Only)<br>
  14180. + *
  14181. + * The application can reset the (micro)frame number
  14182. + * counter inside the core, using this bit. When the
  14183. + * (micro)frame counter is reset, the subsequent SOF
  14184. + * sent out by the core, will have a (micro)frame
  14185. + * number of 0.
  14186. + */
  14187. + unsigned hstfrm : 1;
  14188. + /** Hclk Soft Reset
  14189. + *
  14190. + * The application uses this bit to reset the control logic in
  14191. + * the AHB clock domain. Only AHB clock domain pipelines are
  14192. + * reset.
  14193. + */
  14194. + unsigned hsftrst : 1;
  14195. + /** Core Soft Reset (CSftRst) (Device and Host)
  14196. + *
  14197. + * The application can flush the control logic in the
  14198. + * entire core using this bit. This bit resets the
  14199. + * pipelines in the AHB Clock domain as well as the
  14200. + * PHY Clock domain.
  14201. + *
  14202. + * The state machines are reset to an IDLE state, the
  14203. + * control bits in the CSRs are cleared, all the
  14204. + * transmit FIFOs and the receive FIFO are flushed.
  14205. + *
  14206. + * The status mask bits that control the generation of
  14207. + * the interrupt, are cleared, to clear the
  14208. + * interrupt. The interrupt status bits are not
  14209. + * cleared, so the application can get the status of
  14210. + * any events that occurred in the core after it has
  14211. + * set this bit.
  14212. + *
  14213. + * Any transactions on the AHB are terminated as soon
  14214. + * as possible following the protocol. Any
  14215. + * transactions on the USB are terminated immediately.
  14216. + *
  14217. + * The configuration settings in the CSRs are
  14218. + * unchanged, so the software doesn't have to
  14219. + * reprogram these registers (Device
  14220. + * Configuration/Host Configuration/Core System
  14221. + * Configuration/Core PHY Configuration).
  14222. + *
  14223. + * The application can write to this bit, any time it
  14224. + * wants to reset the core. This is a self clearing
  14225. + * bit and the core clears this bit after all the
  14226. + * necessary logic is reset in the core, which may
  14227. + * take several clocks, depending on the current state
  14228. + * of the core.
  14229. + */
  14230. + unsigned csftrst : 1;
  14231. + } b;
  14232. +} grstctl_t;
  14233. +
  14234. +
  14235. +/**
  14236. + * This union represents the bit fields of the Core Interrupt Mask
  14237. + * Register (GINTMSK). Set/clear the bits using the bit fields then
  14238. + * write the <i>d32</i> value to the register.
  14239. + */
  14240. +typedef union gintmsk_data
  14241. +{
  14242. + /** raw register data */
  14243. + uint32_t d32;
  14244. + /** register bits */
  14245. + struct
  14246. + {
  14247. + unsigned wkupintr : 1;
  14248. + unsigned sessreqintr : 1;
  14249. + unsigned disconnect : 1;
  14250. + unsigned conidstschng : 1;
  14251. + unsigned reserved27 : 1;
  14252. + unsigned ptxfempty : 1;
  14253. + unsigned hcintr : 1;
  14254. + unsigned portintr : 1;
  14255. + unsigned reserved22_23 : 2;
  14256. + unsigned incomplisoout : 1;
  14257. + unsigned incomplisoin : 1;
  14258. + unsigned outepintr : 1;
  14259. + unsigned inepintr : 1;
  14260. + unsigned epmismatch : 1;
  14261. + unsigned reserved16 : 1;
  14262. + unsigned eopframe : 1;
  14263. + unsigned isooutdrop : 1;
  14264. + unsigned enumdone : 1;
  14265. + unsigned usbreset : 1;
  14266. + unsigned usbsuspend : 1;
  14267. + unsigned erlysuspend : 1;
  14268. + unsigned i2cintr : 1;
  14269. + unsigned reserved8 : 1;
  14270. + unsigned goutnakeff : 1;
  14271. + unsigned ginnakeff : 1;
  14272. + unsigned nptxfempty : 1;
  14273. + unsigned rxstsqlvl : 1;
  14274. + unsigned sofintr : 1;
  14275. + unsigned otgintr : 1;
  14276. + unsigned modemismatch : 1;
  14277. + unsigned reserved0 : 1;
  14278. + } b;
  14279. +} gintmsk_data_t;
  14280. +/**
  14281. + * This union represents the bit fields of the Core Interrupt Register
  14282. + * (GINTSTS). Set/clear the bits using the bit fields then write the
  14283. + * <i>d32</i> value to the register.
  14284. + */
  14285. +typedef union gintsts_data
  14286. +{
  14287. + /** raw register data */
  14288. + uint32_t d32;
  14289. +#define DWC_SOF_INTR_MASK 0x0008
  14290. + /** register bits */
  14291. + struct
  14292. + {
  14293. +#define DWC_HOST_MODE 1
  14294. + unsigned wkupintr : 1;
  14295. + unsigned sessreqintr : 1;
  14296. + unsigned disconnect : 1;
  14297. + unsigned conidstschng : 1;
  14298. + unsigned reserved27 : 1;
  14299. + unsigned ptxfempty : 1;
  14300. + unsigned hcintr : 1;
  14301. + unsigned portintr : 1;
  14302. + unsigned reserved22_23 : 2;
  14303. + unsigned incomplisoout : 1;
  14304. + unsigned incomplisoin : 1;
  14305. + unsigned outepintr : 1;
  14306. + unsigned inepint: 1;
  14307. + unsigned epmismatch : 1;
  14308. + unsigned intokenrx : 1;
  14309. + unsigned eopframe : 1;
  14310. + unsigned isooutdrop : 1;
  14311. + unsigned enumdone : 1;
  14312. + unsigned usbreset : 1;
  14313. + unsigned usbsuspend : 1;
  14314. + unsigned erlysuspend : 1;
  14315. + unsigned i2cintr : 1;
  14316. + unsigned reserved8 : 1;
  14317. + unsigned goutnakeff : 1;
  14318. + unsigned ginnakeff : 1;
  14319. + unsigned nptxfempty : 1;
  14320. + unsigned rxstsqlvl : 1;
  14321. + unsigned sofintr : 1;
  14322. + unsigned otgintr : 1;
  14323. + unsigned modemismatch : 1;
  14324. + unsigned curmode : 1;
  14325. + } b;
  14326. +} gintsts_data_t;
  14327. +
  14328. +
  14329. +/**
  14330. + * This union represents the bit fields in the Device Receive Status Read and
  14331. + * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the <i>d32</i>
  14332. + * element then read out the bits using the <i>b</i>it elements.
  14333. + */
  14334. +typedef union device_grxsts_data {
  14335. + /** raw register data */
  14336. + uint32_t d32;
  14337. + /** register bits */
  14338. + struct {
  14339. + unsigned reserved : 7;
  14340. + unsigned fn : 4;
  14341. +#define DWC_STS_DATA_UPDT 0x2 // OUT Data Packet
  14342. +#define DWC_STS_XFER_COMP 0x3 // OUT Data Transfer Complete
  14343. +
  14344. +#define DWC_DSTS_GOUT_NAK 0x1 // Global OUT NAK
  14345. +#define DWC_DSTS_SETUP_COMP 0x4 // Setup Phase Complete
  14346. +#define DWC_DSTS_SETUP_UPDT 0x6 // SETUP Packet
  14347. + unsigned pktsts : 4;
  14348. + unsigned dpid : 2;
  14349. + unsigned bcnt : 11;
  14350. + unsigned epnum : 4;
  14351. + } b;
  14352. +} device_grxsts_data_t;
  14353. +
  14354. +/**
  14355. + * This union represents the bit fields in the Host Receive Status Read and
  14356. + * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the <i>d32</i>
  14357. + * element then read out the bits using the <i>b</i>it elements.
  14358. + */
  14359. +typedef union host_grxsts_data {
  14360. + /** raw register data */
  14361. + uint32_t d32;
  14362. + /** register bits */
  14363. + struct {
  14364. + unsigned reserved31_21 : 11;
  14365. +#define DWC_GRXSTS_PKTSTS_IN 0x2
  14366. +#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP 0x3
  14367. +#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR 0x5
  14368. +#define DWC_GRXSTS_PKTSTS_CH_HALTED 0x7
  14369. + unsigned pktsts : 4;
  14370. + unsigned dpid : 2;
  14371. + unsigned bcnt : 11;
  14372. + unsigned chnum : 4;
  14373. + } b;
  14374. +} host_grxsts_data_t;
  14375. +
  14376. +/**
  14377. + * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ,
  14378. + * GNPTXFSIZ, DPTXFSIZn). Read the register into the <i>d32</i> element then
  14379. + * read out the bits using the <i>b</i>it elements.
  14380. + */
  14381. +typedef union fifosize_data {
  14382. + /** raw register data */
  14383. + uint32_t d32;
  14384. + /** register bits */
  14385. + struct {
  14386. + unsigned depth : 16;
  14387. + unsigned startaddr : 16;
  14388. + } b;
  14389. +} fifosize_data_t;
  14390. +
  14391. +/**
  14392. + * This union represents the bit fields in the Non-Periodic Transmit
  14393. + * FIFO/Queue Status Register (GNPTXSTS). Read the register into the
  14394. + * <i>d32</i> element then read out the bits using the <i>b</i>it
  14395. + * elements.
  14396. + */
  14397. +typedef union gnptxsts_data {
  14398. + /** raw register data */
  14399. + uint32_t d32;
  14400. + /** register bits */
  14401. + struct {
  14402. + unsigned reserved : 1;
  14403. + /** Top of the Non-Periodic Transmit Request Queue
  14404. + * - bits 30:27 - Channel/EP Number
  14405. + * - bits 26:25 - Token Type
  14406. + * - bit 24 - Terminate (Last entry for the selected
  14407. + * channel/EP)
  14408. + * - 2'b00 - IN/OUT
  14409. + * - 2'b01 - Zero Length OUT
  14410. + * - 2'b10 - PING/Complete Split
  14411. + * - 2'b11 - Channel Halt
  14412. +
  14413. + */
  14414. + unsigned nptxqtop_chnep : 4;
  14415. + unsigned nptxqtop_token : 2;
  14416. + unsigned nptxqtop_terminate : 1;
  14417. + unsigned nptxqspcavail : 8;
  14418. + unsigned nptxfspcavail : 16;
  14419. + } b;
  14420. +} gnptxsts_data_t;
  14421. +
  14422. +/**
  14423. + * This union represents the bit fields in the Transmit
  14424. + * FIFO Status Register (DTXFSTS). Read the register into the
  14425. + * <i>d32</i> element then read out the bits using the <i>b</i>it
  14426. + * elements.
  14427. + */
  14428. +typedef union dtxfsts_data /* fscz */ //*
  14429. +{
  14430. + /** raw register data */
  14431. + uint32_t d32;
  14432. + /** register bits */
  14433. + struct {
  14434. + unsigned reserved : 16;
  14435. + unsigned txfspcavail : 16;
  14436. + } b;
  14437. +} dtxfsts_data_t;
  14438. +
  14439. +/**
  14440. + * This union represents the bit fields in the I2C Control Register
  14441. + * (I2CCTL). Read the register into the <i>d32</i> element then read out the
  14442. + * bits using the <i>b</i>it elements.
  14443. + */
  14444. +typedef union gi2cctl_data {
  14445. + /** raw register data */
  14446. + uint32_t d32;
  14447. + /** register bits */
  14448. + struct {
  14449. + unsigned bsydne : 1;
  14450. + unsigned rw : 1;
  14451. + unsigned reserved : 2;
  14452. + unsigned i2cdevaddr : 2;
  14453. + unsigned i2csuspctl : 1;
  14454. + unsigned ack : 1;
  14455. + unsigned i2cen : 1;
  14456. + unsigned addr : 7;
  14457. + unsigned regaddr : 8;
  14458. + unsigned rwdata : 8;
  14459. + } b;
  14460. +} gi2cctl_data_t;
  14461. +
  14462. +/**
  14463. + * This union represents the bit fields in the User HW Config1
  14464. + * Register. Read the register into the <i>d32</i> element then read
  14465. + * out the bits using the <i>b</i>it elements.
  14466. + */
  14467. +typedef union hwcfg1_data {
  14468. + /** raw register data */
  14469. + uint32_t d32;
  14470. + /** register bits */
  14471. + struct {
  14472. + unsigned ep_dir15 : 2;
  14473. + unsigned ep_dir14 : 2;
  14474. + unsigned ep_dir13 : 2;
  14475. + unsigned ep_dir12 : 2;
  14476. + unsigned ep_dir11 : 2;
  14477. + unsigned ep_dir10 : 2;
  14478. + unsigned ep_dir9 : 2;
  14479. + unsigned ep_dir8 : 2;
  14480. + unsigned ep_dir7 : 2;
  14481. + unsigned ep_dir6 : 2;
  14482. + unsigned ep_dir5 : 2;
  14483. + unsigned ep_dir4 : 2;
  14484. + unsigned ep_dir3 : 2;
  14485. + unsigned ep_dir2 : 2;
  14486. + unsigned ep_dir1 : 2;
  14487. + unsigned ep_dir0 : 2;
  14488. + } b;
  14489. +} hwcfg1_data_t;
  14490. +
  14491. +/**
  14492. + * This union represents the bit fields in the User HW Config2
  14493. + * Register. Read the register into the <i>d32</i> element then read
  14494. + * out the bits using the <i>b</i>it elements.
  14495. + */
  14496. +typedef union hwcfg2_data
  14497. +{
  14498. + /** raw register data */
  14499. + uint32_t d32;
  14500. + /** register bits */
  14501. + struct {
  14502. + /* GHWCFG2 */
  14503. + unsigned reserved31 : 1;
  14504. + unsigned dev_token_q_depth : 5;
  14505. + unsigned host_perio_tx_q_depth : 2;
  14506. + unsigned nonperio_tx_q_depth : 2;
  14507. + unsigned rx_status_q_depth : 2;
  14508. + unsigned dynamic_fifo : 1;
  14509. + unsigned perio_ep_supported : 1;
  14510. + unsigned num_host_chan : 4;
  14511. + unsigned num_dev_ep : 4;
  14512. + unsigned fs_phy_type : 2;
  14513. +#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
  14514. +#define DWC_HWCFG2_HS_PHY_TYPE_UTMI 1
  14515. +#define DWC_HWCFG2_HS_PHY_TYPE_ULPI 2
  14516. +#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
  14517. + unsigned hs_phy_type : 2;
  14518. + unsigned point2point : 1;
  14519. + unsigned architecture : 2;
  14520. +#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0
  14521. +#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1
  14522. +#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2
  14523. +#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
  14524. +#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
  14525. +#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
  14526. +#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
  14527. + unsigned op_mode : 3;
  14528. + } b;
  14529. +} hwcfg2_data_t;
  14530. +
  14531. +/**
  14532. + * This union represents the bit fields in the User HW Config3
  14533. + * Register. Read the register into the <i>d32</i> element then read
  14534. + * out the bits using the <i>b</i>it elements.
  14535. + */
  14536. +typedef union hwcfg3_data
  14537. +{
  14538. + /** raw register data */
  14539. + uint32_t d32;
  14540. + /** register bits */
  14541. + struct {
  14542. + /* GHWCFG3 */
  14543. + unsigned dfifo_depth : 16;
  14544. + unsigned reserved15_13 : 3;
  14545. + unsigned ahb_phy_clock_synch : 1;
  14546. + unsigned synch_reset_type : 1;
  14547. + unsigned optional_features : 1;
  14548. + unsigned vendor_ctrl_if : 1;
  14549. + unsigned i2c : 1;
  14550. + unsigned otg_func : 1;
  14551. + unsigned packet_size_cntr_width : 3;
  14552. + unsigned xfer_size_cntr_width : 4;
  14553. + } b;
  14554. +} hwcfg3_data_t;
  14555. +
  14556. +/**
  14557. + * This union represents the bit fields in the User HW Config4
  14558. + * Register. Read the register into the <i>d32</i> element then read
  14559. + * out the bits using the <i>b</i>it elements.
  14560. + */
  14561. +typedef union hwcfg4_data
  14562. +{
  14563. + /** raw register data */
  14564. + uint32_t d32;
  14565. + /** register bits */
  14566. + struct {
  14567. +unsigned reserved31_30 : 2; /* fscz */
  14568. + unsigned num_in_eps : 4;
  14569. + unsigned ded_fifo_en : 1;
  14570. +
  14571. + unsigned session_end_filt_en : 1;
  14572. + unsigned b_valid_filt_en : 1;
  14573. + unsigned a_valid_filt_en : 1;
  14574. + unsigned vbus_valid_filt_en : 1;
  14575. + unsigned iddig_filt_en : 1;
  14576. + unsigned num_dev_mode_ctrl_ep : 4;
  14577. + unsigned utmi_phy_data_width : 2;
  14578. + unsigned min_ahb_freq : 9;
  14579. + unsigned power_optimiz : 1;
  14580. + unsigned num_dev_perio_in_ep : 4;
  14581. + } b;
  14582. +} hwcfg4_data_t;
  14583. +
  14584. +////////////////////////////////////////////
  14585. +// Device Registers
  14586. +/**
  14587. + * Device Global Registers. <i>Offsets 800h-BFFh</i>
  14588. + *
  14589. + * The following structures define the size and relative field offsets
  14590. + * for the Device Mode Registers.
  14591. + *
  14592. + * <i>These registers are visible only in Device mode and must not be
  14593. + * accessed in Host mode, as the results are unknown.</i>
  14594. + */
  14595. +typedef struct dwc_otg_dev_global_regs
  14596. +{
  14597. + /** Device Configuration Register. <i>Offset 800h</i> */
  14598. + volatile uint32_t dcfg;
  14599. + /** Device Control Register. <i>Offset: 804h</i> */
  14600. + volatile uint32_t dctl;
  14601. + /** Device Status Register (Read Only). <i>Offset: 808h</i> */
  14602. + volatile uint32_t dsts;
  14603. + /** Reserved. <i>Offset: 80Ch</i> */
  14604. + uint32_t unused;
  14605. + /** Device IN Endpoint Common Interrupt Mask
  14606. + * Register. <i>Offset: 810h</i> */
  14607. + volatile uint32_t diepmsk;
  14608. + /** Device OUT Endpoint Common Interrupt Mask
  14609. + * Register. <i>Offset: 814h</i> */
  14610. + volatile uint32_t doepmsk;
  14611. + /** Device All Endpoints Interrupt Register. <i>Offset: 818h</i> */
  14612. + volatile uint32_t daint;
  14613. + /** Device All Endpoints Interrupt Mask Register. <i>Offset:
  14614. + * 81Ch</i> */
  14615. + volatile uint32_t daintmsk;
  14616. + /** Device IN Token Queue Read Register-1 (Read Only).
  14617. + * <i>Offset: 820h</i> */
  14618. + volatile uint32_t dtknqr1;
  14619. + /** Device IN Token Queue Read Register-2 (Read Only).
  14620. + * <i>Offset: 824h</i> */
  14621. + volatile uint32_t dtknqr2;
  14622. + /** Device VBUS discharge Register. <i>Offset: 828h</i> */
  14623. + volatile uint32_t dvbusdis;
  14624. + /** Device VBUS Pulse Register. <i>Offset: 82Ch</i> */
  14625. + volatile uint32_t dvbuspulse;
  14626. + /** Device IN Token Queue Read Register-3 (Read Only).
  14627. + * Device Thresholding control register (Read/Write)
  14628. + * <i>Offset: 830h</i> */
  14629. + volatile uint32_t dtknqr3_dthrctl;
  14630. + /** Device IN Token Queue Read Register-4 (Read Only). /
  14631. + * Device IN EPs empty Inr. Mask Register (Read/Write)
  14632. + * <i>Offset: 834h</i> */
  14633. + volatile uint32_t dtknqr4_fifoemptymsk;
  14634. +} dwc_otg_device_global_regs_t;
  14635. +
  14636. +/**
  14637. + * This union represents the bit fields in the Device Configuration
  14638. + * Register. Read the register into the <i>d32</i> member then
  14639. + * set/clear the bits using the <i>b</i>it elements. Write the
  14640. + * <i>d32</i> member to the dcfg register.
  14641. + */
  14642. +typedef union dcfg_data
  14643. +{
  14644. + /** raw register data */
  14645. + uint32_t d32;
  14646. + /** register bits */
  14647. + struct {
  14648. + unsigned reserved31_23 : 9;
  14649. + /** In Endpoint Mis-match count */
  14650. + unsigned epmscnt : 5;
  14651. + unsigned reserved13_17 : 5;
  14652. + /** Periodic Frame Interval */
  14653. +#define DWC_DCFG_FRAME_INTERVAL_80 0
  14654. +#define DWC_DCFG_FRAME_INTERVAL_85 1
  14655. +#define DWC_DCFG_FRAME_INTERVAL_90 2
  14656. +#define DWC_DCFG_FRAME_INTERVAL_95 3
  14657. + unsigned perfrint : 2;
  14658. + /** Device Addresses */
  14659. + unsigned devaddr : 7;
  14660. + unsigned reserved3 : 1;
  14661. + /** Non Zero Length Status OUT Handshake */
  14662. +#define DWC_DCFG_SEND_STALL 1
  14663. + unsigned nzstsouthshk : 1;
  14664. + /** Device Speed */
  14665. + unsigned devspd : 2;
  14666. + } b;
  14667. +} dcfg_data_t;
  14668. +
  14669. +/**
  14670. + * This union represents the bit fields in the Device Control
  14671. + * Register. Read the register into the <i>d32</i> member then
  14672. + * set/clear the bits using the <i>b</i>it elements.
  14673. + */
  14674. +typedef union dctl_data
  14675. +{
  14676. + /** raw register data */
  14677. + uint32_t d32;
  14678. + /** register bits */
  14679. + struct {
  14680. + unsigned reserved : 20;
  14681. + /** Power-On Programming Done */
  14682. + unsigned pwronprgdone : 1;
  14683. + /** Clear Global OUT NAK */
  14684. + unsigned cgoutnak : 1;
  14685. + /** Set Global OUT NAK */
  14686. + unsigned sgoutnak : 1;
  14687. + /** Clear Global Non-Periodic IN NAK */
  14688. + unsigned cgnpinnak : 1;
  14689. + /** Set Global Non-Periodic IN NAK */
  14690. + unsigned sgnpinnak : 1;
  14691. + /** Test Control */
  14692. + unsigned tstctl : 3;
  14693. + /** Global OUT NAK Status */
  14694. + unsigned goutnaksts : 1;
  14695. + /** Global Non-Periodic IN NAK Status */
  14696. + unsigned gnpinnaksts : 1;
  14697. + /** Soft Disconnect */
  14698. + unsigned sftdiscon : 1;
  14699. + /** Remote Wakeup */
  14700. + unsigned rmtwkupsig : 1;
  14701. + } b;
  14702. +} dctl_data_t;
  14703. +
  14704. +/**
  14705. + * This union represents the bit fields in the Device Status
  14706. + * Register. Read the register into the <i>d32</i> member then
  14707. + * set/clear the bits using the <i>b</i>it elements.
  14708. + */
  14709. +typedef union dsts_data
  14710. +{
  14711. + /** raw register data */
  14712. + uint32_t d32;
  14713. + /** register bits */
  14714. + struct {
  14715. + unsigned reserved22_31 : 10;
  14716. + /** Frame or Microframe Number of the received SOF */
  14717. + unsigned soffn : 14;
  14718. + unsigned reserved4_7: 4;
  14719. + /** Erratic Error */
  14720. + unsigned errticerr : 1;
  14721. + /** Enumerated Speed */
  14722. +#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
  14723. +#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
  14724. +#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ 2
  14725. +#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ 3
  14726. + unsigned enumspd : 2;
  14727. + /** Suspend Status */
  14728. + unsigned suspsts : 1;
  14729. + } b;
  14730. +} dsts_data_t;
  14731. +
  14732. +
  14733. +/**
  14734. + * This union represents the bit fields in the Device IN EP Interrupt
  14735. + * Register and the Device IN EP Common Mask Register.
  14736. + *
  14737. + * - Read the register into the <i>d32</i> member then set/clear the
  14738. + * bits using the <i>b</i>it elements.
  14739. + */
  14740. +typedef union diepint_data
  14741. +{
  14742. + /** raw register data */
  14743. + uint32_t d32;
  14744. + /** register bits */
  14745. + struct {
  14746. + unsigned reserved07_31 : 23;
  14747. + unsigned txfifoundrn : 1;
  14748. + /** IN Endpoint HAK Effective mask */
  14749. + unsigned emptyintr : 1;
  14750. + /** IN Endpoint NAK Effective mask */
  14751. + unsigned inepnakeff : 1;
  14752. + /** IN Token Received with EP mismatch mask */
  14753. + unsigned intknepmis : 1;
  14754. + /** IN Token received with TxF Empty mask */
  14755. + unsigned intktxfemp : 1;
  14756. + /** TimeOUT Handshake mask (non-ISOC EPs) */
  14757. + unsigned timeout : 1;
  14758. + /** AHB Error mask */
  14759. + unsigned ahberr : 1;
  14760. + /** Endpoint disable mask */
  14761. + unsigned epdisabled : 1;
  14762. + /** Transfer complete mask */
  14763. + unsigned xfercompl : 1;
  14764. + } b;
  14765. +} diepint_data_t;
  14766. +/**
  14767. + * This union represents the bit fields in the Device IN EP Common
  14768. + * Interrupt Mask Register.
  14769. + */
  14770. +typedef union diepint_data diepmsk_data_t;
  14771. +
  14772. +/**
  14773. + * This union represents the bit fields in the Device OUT EP Interrupt
  14774. + * Registerand Device OUT EP Common Interrupt Mask Register.
  14775. + *
  14776. + * - Read the register into the <i>d32</i> member then set/clear the
  14777. + * bits using the <i>b</i>it elements.
  14778. + */
  14779. +typedef union doepint_data
  14780. +{
  14781. + /** raw register data */
  14782. + uint32_t d32;
  14783. + /** register bits */
  14784. + struct {
  14785. + unsigned reserved04_31 : 27;
  14786. + /** OUT Token Received when Endpoint Disabled */
  14787. + unsigned outtknepdis : 1;
  14788. + /** Setup Phase Done (contorl EPs) */
  14789. + unsigned setup : 1;
  14790. + /** AHB Error */
  14791. + unsigned ahberr : 1;
  14792. + /** Endpoint disable */
  14793. + unsigned epdisabled : 1;
  14794. + /** Transfer complete */
  14795. + unsigned xfercompl : 1;
  14796. + } b;
  14797. +} doepint_data_t;
  14798. +/**
  14799. + * This union represents the bit fields in the Device OUT EP Common
  14800. + * Interrupt Mask Register.
  14801. + */
  14802. +typedef union doepint_data doepmsk_data_t;
  14803. +
  14804. +
  14805. +/**
  14806. + * This union represents the bit fields in the Device All EP Interrupt
  14807. + * and Mask Registers.
  14808. + * - Read the register into the <i>d32</i> member then set/clear the
  14809. + * bits using the <i>b</i>it elements.
  14810. + */
  14811. +typedef union daint_data
  14812. +{
  14813. + /** raw register data */
  14814. + uint32_t d32;
  14815. + /** register bits */
  14816. + struct {
  14817. + /** OUT Endpoint bits */
  14818. + unsigned out : 16;
  14819. + /** IN Endpoint bits */
  14820. + unsigned in : 16;
  14821. + } ep;
  14822. + struct {
  14823. + /** OUT Endpoint bits */
  14824. + unsigned outep15 : 1;
  14825. + unsigned outep14 : 1;
  14826. + unsigned outep13 : 1;
  14827. + unsigned outep12 : 1;
  14828. + unsigned outep11 : 1;
  14829. + unsigned outep10 : 1;
  14830. + unsigned outep9 : 1;
  14831. + unsigned outep8 : 1;
  14832. + unsigned outep7 : 1;
  14833. + unsigned outep6 : 1;
  14834. + unsigned outep5 : 1;
  14835. + unsigned outep4 : 1;
  14836. + unsigned outep3 : 1;
  14837. + unsigned outep2 : 1;
  14838. + unsigned outep1 : 1;
  14839. + unsigned outep0 : 1;
  14840. + /** IN Endpoint bits */
  14841. + unsigned inep15 : 1;
  14842. + unsigned inep14 : 1;
  14843. + unsigned inep13 : 1;
  14844. + unsigned inep12 : 1;
  14845. + unsigned inep11 : 1;
  14846. + unsigned inep10 : 1;
  14847. + unsigned inep9 : 1;
  14848. + unsigned inep8 : 1;
  14849. + unsigned inep7 : 1;
  14850. + unsigned inep6 : 1;
  14851. + unsigned inep5 : 1;
  14852. + unsigned inep4 : 1;
  14853. + unsigned inep3 : 1;
  14854. + unsigned inep2 : 1;
  14855. + unsigned inep1 : 1;
  14856. + unsigned inep0 : 1;
  14857. + } b;
  14858. +} daint_data_t;
  14859. +
  14860. +/**
  14861. + * This union represents the bit fields in the Device IN Token Queue
  14862. + * Read Registers.
  14863. + * - Read the register into the <i>d32</i> member.
  14864. + * - READ-ONLY Register
  14865. + */
  14866. +typedef union dtknq1_data
  14867. +{
  14868. + /** raw register data */
  14869. + uint32_t d32;
  14870. + /** register bits */
  14871. + struct {
  14872. + /** EP Numbers of IN Tokens 0 ... 4 */
  14873. + unsigned epnums0_5 : 24;
  14874. + /** write pointer has wrapped. */
  14875. + unsigned wrap_bit : 1;
  14876. + /** Reserved */
  14877. + unsigned reserved05_06 : 2;
  14878. + /** In Token Queue Write Pointer */
  14879. + unsigned intknwptr : 5;
  14880. + }b;
  14881. +} dtknq1_data_t;
  14882. +
  14883. +/**
  14884. + * This union represents Threshold control Register
  14885. + * - Read and write the register into the <i>d32</i> member.
  14886. + * - READ-WRITABLE Register
  14887. + */
  14888. +typedef union dthrctl_data //* /*fscz */
  14889. +{
  14890. + /** raw register data */
  14891. + uint32_t d32;
  14892. + /** register bits */
  14893. + struct {
  14894. + /** Reserved */
  14895. + unsigned reserved26_31 : 6;
  14896. + /** Rx Thr. Length */
  14897. + unsigned rx_thr_len : 9;
  14898. + /** Rx Thr. Enable */
  14899. + unsigned rx_thr_en : 1;
  14900. + /** Reserved */
  14901. + unsigned reserved11_15 : 5;
  14902. + /** Tx Thr. Length */
  14903. + unsigned tx_thr_len : 9;
  14904. + /** ISO Tx Thr. Enable */
  14905. + unsigned iso_thr_en : 1;
  14906. + /** non ISO Tx Thr. Enable */
  14907. + unsigned non_iso_thr_en : 1;
  14908. +
  14909. + }b;
  14910. +} dthrctl_data_t;
  14911. +
  14912. +/**
  14913. + * Device Logical IN Endpoint-Specific Registers. <i>Offsets
  14914. + * 900h-AFCh</i>
  14915. + *
  14916. + * There will be one set of endpoint registers per logical endpoint
  14917. + * implemented.
  14918. + *
  14919. + * <i>These registers are visible only in Device mode and must not be
  14920. + * accessed in Host mode, as the results are unknown.</i>
  14921. + */
  14922. +typedef struct dwc_otg_dev_in_ep_regs
  14923. +{
  14924. + /** Device IN Endpoint Control Register. <i>Offset:900h +
  14925. + * (ep_num * 20h) + 00h</i> */
  14926. + volatile uint32_t diepctl;
  14927. + /** Reserved. <i>Offset:900h + (ep_num * 20h) + 04h</i> */
  14928. + uint32_t reserved04;
  14929. + /** Device IN Endpoint Interrupt Register. <i>Offset:900h +
  14930. + * (ep_num * 20h) + 08h</i> */
  14931. + volatile uint32_t diepint;
  14932. + /** Reserved. <i>Offset:900h + (ep_num * 20h) + 0Ch</i> */
  14933. + uint32_t reserved0C;
  14934. + /** Device IN Endpoint Transfer Size
  14935. + * Register. <i>Offset:900h + (ep_num * 20h) + 10h</i> */
  14936. + volatile uint32_t dieptsiz;
  14937. + /** Device IN Endpoint DMA Address Register. <i>Offset:900h +
  14938. + * (ep_num * 20h) + 14h</i> */
  14939. + volatile uint32_t diepdma;
  14940. + /** Reserved. <i>Offset:900h + (ep_num * 20h) + 18h - 900h +
  14941. + * (ep_num * 20h) + 1Ch</i>*/
  14942. + volatile uint32_t dtxfsts;
  14943. + /** Reserved. <i>Offset:900h + (ep_num * 20h) + 1Ch - 900h +
  14944. + * (ep_num * 20h) + 1Ch</i>*/
  14945. + uint32_t reserved18;
  14946. +} dwc_otg_dev_in_ep_regs_t;
  14947. +
  14948. +/**
  14949. + * Device Logical OUT Endpoint-Specific Registers. <i>Offsets:
  14950. + * B00h-CFCh</i>
  14951. + *
  14952. + * There will be one set of endpoint registers per logical endpoint
  14953. + * implemented.
  14954. + *
  14955. + * <i>These registers are visible only in Device mode and must not be
  14956. + * accessed in Host mode, as the results are unknown.</i>
  14957. + */
  14958. +typedef struct dwc_otg_dev_out_ep_regs
  14959. +{
  14960. + /** Device OUT Endpoint Control Register. <i>Offset:B00h +
  14961. + * (ep_num * 20h) + 00h</i> */
  14962. + volatile uint32_t doepctl;
  14963. + /** Device OUT Endpoint Frame number Register. <i>Offset:
  14964. + * B00h + (ep_num * 20h) + 04h</i> */
  14965. + volatile uint32_t doepfn;
  14966. + /** Device OUT Endpoint Interrupt Register. <i>Offset:B00h +
  14967. + * (ep_num * 20h) + 08h</i> */
  14968. + volatile uint32_t doepint;
  14969. + /** Reserved. <i>Offset:B00h + (ep_num * 20h) + 0Ch</i> */
  14970. + uint32_t reserved0C;
  14971. + /** Device OUT Endpoint Transfer Size Register. <i>Offset:
  14972. + * B00h + (ep_num * 20h) + 10h</i> */
  14973. + volatile uint32_t doeptsiz;
  14974. + /** Device OUT Endpoint DMA Address Register. <i>Offset:B00h
  14975. + * + (ep_num * 20h) + 14h</i> */
  14976. + volatile uint32_t doepdma;
  14977. + /** Reserved. <i>Offset:B00h + (ep_num * 20h) + 18h - B00h +
  14978. + * (ep_num * 20h) + 1Ch</i> */
  14979. + uint32_t unused[2];
  14980. +} dwc_otg_dev_out_ep_regs_t;
  14981. +
  14982. +/**
  14983. + * This union represents the bit fields in the Device EP Control
  14984. + * Register. Read the register into the <i>d32</i> member then
  14985. + * set/clear the bits using the <i>b</i>it elements.
  14986. + */
  14987. +typedef union depctl_data
  14988. +{
  14989. + /** raw register data */
  14990. + uint32_t d32;
  14991. + /** register bits */
  14992. + struct {
  14993. + /** Endpoint Enable */
  14994. + unsigned epena : 1;
  14995. + /** Endpoint Disable */
  14996. + unsigned epdis : 1;
  14997. + /** Set DATA1 PID (INTR/Bulk IN and OUT endpoints)
  14998. + * Writing to this field sets the Endpoint DPID (DPID)
  14999. + * field in this register to DATA1 Set Odd
  15000. + * (micro)frame (SetOddFr) (ISO IN and OUT Endpoints)
  15001. + * Writing to this field sets the Even/Odd
  15002. + * (micro)frame (EO_FrNum) field to odd (micro) frame.
  15003. + */
  15004. + unsigned setd1pid : 1;
  15005. + /** Set DATA0 PID (INTR/Bulk IN and OUT endpoints)
  15006. + * Writing to this field sets the Endpoint DPID (DPID)
  15007. + * field in this register to DATA0. Set Even
  15008. + * (micro)frame (SetEvenFr) (ISO IN and OUT Endpoints)
  15009. + * Writing to this field sets the Even/Odd
  15010. + * (micro)frame (EO_FrNum) field to even (micro)
  15011. + * frame.
  15012. + */
  15013. + unsigned setd0pid : 1;
  15014. + /** Set NAK */
  15015. + unsigned snak : 1;
  15016. + /** Clear NAK */
  15017. + unsigned cnak : 1;
  15018. + /** Tx Fifo Number
  15019. + * IN EPn/IN EP0
  15020. + * OUT EPn/OUT EP0 - reserved */
  15021. + unsigned txfnum : 4;
  15022. + /** Stall Handshake */
  15023. + unsigned stall : 1;
  15024. + /** Snoop Mode
  15025. + * OUT EPn/OUT EP0
  15026. + * IN EPn/IN EP0 - reserved */
  15027. + unsigned snp : 1;
  15028. + /** Endpoint Type
  15029. + * 2'b00: Control
  15030. + * 2'b01: Isochronous
  15031. + * 2'b10: Bulk
  15032. + * 2'b11: Interrupt */
  15033. + unsigned eptype : 2;
  15034. + /** NAK Status */
  15035. + unsigned naksts : 1;
  15036. + /** Endpoint DPID (INTR/Bulk IN and OUT endpoints)
  15037. + * This field contains the PID of the packet going to
  15038. + * be received or transmitted on this endpoint. The
  15039. + * application should program the PID of the first
  15040. + * packet going to be received or transmitted on this
  15041. + * endpoint , after the endpoint is
  15042. + * activated. Application use the SetD1PID and
  15043. + * SetD0PID fields of this register to program either
  15044. + * D0 or D1 PID.
  15045. + *
  15046. + * The encoding for this field is
  15047. + * - 0: D0
  15048. + * - 1: D1
  15049. + */
  15050. + unsigned dpid : 1;
  15051. + /** USB Active Endpoint */
  15052. + unsigned usbactep : 1;
  15053. + /** Next Endpoint
  15054. + * IN EPn/IN EP0
  15055. + * OUT EPn/OUT EP0 - reserved */
  15056. + unsigned nextep : 4;
  15057. + /** Maximum Packet Size
  15058. + * IN/OUT EPn
  15059. + * IN/OUT EP0 - 2 bits
  15060. + * 2'b00: 64 Bytes
  15061. + * 2'b01: 32
  15062. + * 2'b10: 16
  15063. + * 2'b11: 8 */
  15064. +#define DWC_DEP0CTL_MPS_64 0
  15065. +#define DWC_DEP0CTL_MPS_32 1
  15066. +#define DWC_DEP0CTL_MPS_16 2
  15067. +#define DWC_DEP0CTL_MPS_8 3
  15068. + unsigned mps : 11;
  15069. + } b;
  15070. +} depctl_data_t;
  15071. +
  15072. +/**
  15073. + * This union represents the bit fields in the Device EP Transfer
  15074. + * Size Register. Read the register into the <i>d32</i> member then
  15075. + * set/clear the bits using the <i>b</i>it elements.
  15076. + */
  15077. +typedef union deptsiz_data
  15078. +{
  15079. + /** raw register data */
  15080. + uint32_t d32;
  15081. + /** register bits */
  15082. + struct {
  15083. + unsigned reserved : 1;
  15084. + /** Multi Count - Periodic IN endpoints */
  15085. + unsigned mc : 2;
  15086. + /** Packet Count */
  15087. + unsigned pktcnt : 10;
  15088. + /** Transfer size */
  15089. + unsigned xfersize : 19;
  15090. + } b;
  15091. +} deptsiz_data_t;
  15092. +
  15093. +/**
  15094. + * This union represents the bit fields in the Device EP 0 Transfer
  15095. + * Size Register. Read the register into the <i>d32</i> member then
  15096. + * set/clear the bits using the <i>b</i>it elements.
  15097. + */
  15098. +typedef union deptsiz0_data
  15099. +{
  15100. + /** raw register data */
  15101. + uint32_t d32;
  15102. + /** register bits */
  15103. + struct {
  15104. + unsigned reserved31 : 1;
  15105. + /**Setup Packet Count (DOEPTSIZ0 Only) */
  15106. + unsigned supcnt : 2;
  15107. + /** Reserved */
  15108. + unsigned reserved28_20 : 9;
  15109. + /** Packet Count */
  15110. + unsigned pktcnt : 1;
  15111. + /** Reserved */
  15112. + unsigned reserved18_7 : 12;
  15113. + /** Transfer size */
  15114. + unsigned xfersize : 7;
  15115. + } b;
  15116. +} deptsiz0_data_t;
  15117. +
  15118. +
  15119. +/** Maximum number of Periodic FIFOs */
  15120. +#define MAX_PERIO_FIFOS 15
  15121. +/** Maximum number of TX FIFOs */
  15122. +#define MAX_TX_FIFOS 15
  15123. +/** Maximum number of Endpoints/HostChannels */
  15124. +#define MAX_EPS_CHANNELS 16
  15125. +//#define MAX_EPS_CHANNELS 4
  15126. +
  15127. +/**
  15128. + * The dwc_otg_dev_if structure contains information needed to manage
  15129. + * the DWC_otg controller acting in device mode. It represents the
  15130. + * programming view of the device-specific aspects of the controller.
  15131. + */
  15132. +typedef struct dwc_otg_dev_if {
  15133. + /** Pointer to device Global registers.
  15134. + * Device Global Registers starting at offset 800h
  15135. + */
  15136. + dwc_otg_device_global_regs_t *dev_global_regs;
  15137. +#define DWC_DEV_GLOBAL_REG_OFFSET 0x800
  15138. +
  15139. + /**
  15140. + * Device Logical IN Endpoint-Specific Registers 900h-AFCh
  15141. + */
  15142. + dwc_otg_dev_in_ep_regs_t *in_ep_regs[MAX_EPS_CHANNELS];
  15143. +#define DWC_DEV_IN_EP_REG_OFFSET 0x900
  15144. +#define DWC_EP_REG_OFFSET 0x20
  15145. +
  15146. + /** Device Logical OUT Endpoint-Specific Registers B00h-CFCh */
  15147. + dwc_otg_dev_out_ep_regs_t *out_ep_regs[MAX_EPS_CHANNELS];
  15148. +#define DWC_DEV_OUT_EP_REG_OFFSET 0xB00
  15149. +
  15150. + /* Device configuration information*/
  15151. + uint8_t speed; /**< Device Speed 0: Unknown, 1: LS, 2:FS, 3: HS */
  15152. + //uint8_t num_eps; /**< Number of EPs range: 0-16 (includes EP0) */
  15153. + //uint8_t num_perio_eps; /**< # of Periodic EP range: 0-15 */
  15154. + /*fscz */
  15155. + uint8_t num_in_eps; /**< Number # of Tx EP range: 0-15 exept ep0 */
  15156. + uint8_t num_out_eps; /**< Number # of Rx EP range: 0-15 exept ep 0*/
  15157. +
  15158. + /** Size of periodic FIFOs (Bytes) */
  15159. + uint16_t perio_tx_fifo_size[MAX_PERIO_FIFOS];
  15160. +
  15161. + /** Size of Tx FIFOs (Bytes) */
  15162. + uint16_t tx_fifo_size[MAX_TX_FIFOS];
  15163. +
  15164. + /** Thresholding enable flags and length varaiables **/
  15165. + uint16_t rx_thr_en;
  15166. + uint16_t iso_tx_thr_en;
  15167. + uint16_t non_iso_tx_thr_en;
  15168. +
  15169. + uint16_t rx_thr_length;
  15170. + uint16_t tx_thr_length;
  15171. +} dwc_otg_dev_if_t;
  15172. +
  15173. +/**
  15174. + * This union represents the bit fields in the Power and Clock Gating Control
  15175. + * Register. Read the register into the <i>d32</i> member then set/clear the
  15176. + * bits using the <i>b</i>it elements.
  15177. + */
  15178. +typedef union pcgcctl_data
  15179. +{
  15180. + /** raw register data */
  15181. + uint32_t d32;
  15182. +
  15183. + /** register bits */
  15184. + struct {
  15185. + unsigned reserved31_05 : 27;
  15186. + /** PHY Suspended */
  15187. + unsigned physuspended : 1;
  15188. + /** Reset Power Down Modules */
  15189. + unsigned rstpdwnmodule : 1;
  15190. + /** Power Clamp */
  15191. + unsigned pwrclmp : 1;
  15192. + /** Gate Hclk */
  15193. + unsigned gatehclk : 1;
  15194. + /** Stop Pclk */
  15195. + unsigned stoppclk : 1;
  15196. + } b;
  15197. +} pcgcctl_data_t;
  15198. +
  15199. +/////////////////////////////////////////////////
  15200. +// Host Mode Register Structures
  15201. +//
  15202. +/**
  15203. + * The Host Global Registers structure defines the size and relative
  15204. + * field offsets for the Host Mode Global Registers. Host Global
  15205. + * Registers offsets 400h-7FFh.
  15206. +*/
  15207. +typedef struct dwc_otg_host_global_regs
  15208. +{
  15209. + /** Host Configuration Register. <i>Offset: 400h</i> */
  15210. + volatile uint32_t hcfg;
  15211. + /** Host Frame Interval Register. <i>Offset: 404h</i> */
  15212. + volatile uint32_t hfir;
  15213. + /** Host Frame Number / Frame Remaining Register. <i>Offset: 408h</i> */
  15214. + volatile uint32_t hfnum;
  15215. + /** Reserved. <i>Offset: 40Ch</i> */
  15216. + uint32_t reserved40C;
  15217. + /** Host Periodic Transmit FIFO/ Queue Status Register. <i>Offset: 410h</i> */
  15218. + volatile uint32_t hptxsts;
  15219. + /** Host All Channels Interrupt Register. <i>Offset: 414h</i> */
  15220. + volatile uint32_t haint;
  15221. + /** Host All Channels Interrupt Mask Register. <i>Offset: 418h</i> */
  15222. + volatile uint32_t haintmsk;
  15223. +} dwc_otg_host_global_regs_t;
  15224. +
  15225. +/**
  15226. + * This union represents the bit fields in the Host Configuration Register.
  15227. + * Read the register into the <i>d32</i> member then set/clear the bits using
  15228. + * the <i>b</i>it elements. Write the <i>d32</i> member to the hcfg register.
  15229. + */
  15230. +typedef union hcfg_data
  15231. +{
  15232. + /** raw register data */
  15233. + uint32_t d32;
  15234. +
  15235. + /** register bits */
  15236. + struct {
  15237. + /** Reserved */
  15238. + //unsigned reserved31_03 : 29;
  15239. + /** FS/LS Only Support */
  15240. + unsigned fslssupp : 1;
  15241. + /** FS/LS Phy Clock Select */
  15242. +#define DWC_HCFG_30_60_MHZ 0
  15243. +#define DWC_HCFG_48_MHZ 1
  15244. +#define DWC_HCFG_6_MHZ 2
  15245. + unsigned fslspclksel : 2;
  15246. + } b;
  15247. +} hcfg_data_t;
  15248. +
  15249. +/**
  15250. + * This union represents the bit fields in the Host Frame Remaing/Number
  15251. + * Register.
  15252. + */
  15253. +typedef union hfir_data
  15254. +{
  15255. + /** raw register data */
  15256. + uint32_t d32;
  15257. +
  15258. + /** register bits */
  15259. + struct {
  15260. + unsigned reserved : 16;
  15261. + unsigned frint : 16;
  15262. + } b;
  15263. +} hfir_data_t;
  15264. +
  15265. +/**
  15266. + * This union represents the bit fields in the Host Frame Remaing/Number
  15267. + * Register.
  15268. + */
  15269. +typedef union hfnum_data
  15270. +{
  15271. + /** raw register data */
  15272. + uint32_t d32;
  15273. +
  15274. + /** register bits */
  15275. + struct {
  15276. + unsigned frrem : 16;
  15277. +#define DWC_HFNUM_MAX_FRNUM 0x3FFF
  15278. + unsigned frnum : 16;
  15279. + } b;
  15280. +} hfnum_data_t;
  15281. +
  15282. +typedef union hptxsts_data
  15283. +{
  15284. + /** raw register data */
  15285. + uint32_t d32;
  15286. +
  15287. + /** register bits */
  15288. + struct {
  15289. + /** Top of the Periodic Transmit Request Queue
  15290. + * - bit 24 - Terminate (last entry for the selected channel)
  15291. + * - bits 26:25 - Token Type
  15292. + * - 2'b00 - Zero length
  15293. + * - 2'b01 - Ping
  15294. + * - 2'b10 - Disable
  15295. + * - bits 30:27 - Channel Number
  15296. + * - bit 31 - Odd/even microframe
  15297. + */
  15298. + unsigned ptxqtop_odd : 1;
  15299. + unsigned ptxqtop_chnum : 4;
  15300. + unsigned ptxqtop_token : 2;
  15301. + unsigned ptxqtop_terminate : 1;
  15302. + unsigned ptxqspcavail : 8;
  15303. + unsigned ptxfspcavail : 16;
  15304. + } b;
  15305. +} hptxsts_data_t;
  15306. +
  15307. +/**
  15308. + * This union represents the bit fields in the Host Port Control and Status
  15309. + * Register. Read the register into the <i>d32</i> member then set/clear the
  15310. + * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
  15311. + * hprt0 register.
  15312. + */
  15313. +typedef union hprt0_data
  15314. +{
  15315. + /** raw register data */
  15316. + uint32_t d32;
  15317. + /** register bits */
  15318. + struct {
  15319. + unsigned reserved19_31 : 13;
  15320. +#define DWC_HPRT0_PRTSPD_HIGH_SPEED 0
  15321. +#define DWC_HPRT0_PRTSPD_FULL_SPEED 1
  15322. +#define DWC_HPRT0_PRTSPD_LOW_SPEED 2
  15323. + unsigned prtspd : 2;
  15324. + unsigned prttstctl : 4;
  15325. + unsigned prtpwr : 1;
  15326. + unsigned prtlnsts : 2;
  15327. + unsigned reserved9 : 1;
  15328. + unsigned prtrst : 1;
  15329. + unsigned prtsusp : 1;
  15330. + unsigned prtres : 1;
  15331. + unsigned prtovrcurrchng : 1;
  15332. + unsigned prtovrcurract : 1;
  15333. + unsigned prtenchng : 1;
  15334. + unsigned prtena : 1;
  15335. + unsigned prtconndet : 1;
  15336. + unsigned prtconnsts : 1;
  15337. + } b;
  15338. +} hprt0_data_t;
  15339. +
  15340. +/**
  15341. + * This union represents the bit fields in the Host All Interrupt
  15342. + * Register.
  15343. + */
  15344. +typedef union haint_data
  15345. +{
  15346. + /** raw register data */
  15347. + uint32_t d32;
  15348. + /** register bits */
  15349. + struct {
  15350. + unsigned reserved : 16;
  15351. + unsigned ch15 : 1;
  15352. + unsigned ch14 : 1;
  15353. + unsigned ch13 : 1;
  15354. + unsigned ch12 : 1;
  15355. + unsigned ch11 : 1;
  15356. + unsigned ch10 : 1;
  15357. + unsigned ch9 : 1;
  15358. + unsigned ch8 : 1;
  15359. + unsigned ch7 : 1;
  15360. + unsigned ch6 : 1;
  15361. + unsigned ch5 : 1;
  15362. + unsigned ch4 : 1;
  15363. + unsigned ch3 : 1;
  15364. + unsigned ch2 : 1;
  15365. + unsigned ch1 : 1;
  15366. + unsigned ch0 : 1;
  15367. + } b;
  15368. + struct {
  15369. + unsigned reserved : 16;
  15370. + unsigned chint : 16;
  15371. + } b2;
  15372. +} haint_data_t;
  15373. +
  15374. +/**
  15375. + * This union represents the bit fields in the Host All Interrupt
  15376. + * Register.
  15377. + */
  15378. +typedef union haintmsk_data
  15379. +{
  15380. + /** raw register data */
  15381. + uint32_t d32;
  15382. + /** register bits */
  15383. + struct {
  15384. + unsigned reserved : 16;
  15385. + unsigned ch15 : 1;
  15386. + unsigned ch14 : 1;
  15387. + unsigned ch13 : 1;
  15388. + unsigned ch12 : 1;
  15389. + unsigned ch11 : 1;
  15390. + unsigned ch10 : 1;
  15391. + unsigned ch9 : 1;
  15392. + unsigned ch8 : 1;
  15393. + unsigned ch7 : 1;
  15394. + unsigned ch6 : 1;
  15395. + unsigned ch5 : 1;
  15396. + unsigned ch4 : 1;
  15397. + unsigned ch3 : 1;
  15398. + unsigned ch2 : 1;
  15399. + unsigned ch1 : 1;
  15400. + unsigned ch0 : 1;
  15401. + } b;
  15402. + struct {
  15403. + unsigned reserved : 16;
  15404. + unsigned chint : 16;
  15405. + } b2;
  15406. +} haintmsk_data_t;
  15407. +
  15408. +/**
  15409. + * Host Channel Specific Registers. <i>500h-5FCh</i>
  15410. + */
  15411. +typedef struct dwc_otg_hc_regs
  15412. +{
  15413. + /** Host Channel 0 Characteristic Register. <i>Offset: 500h + (chan_num * 20h) + 00h</i> */
  15414. + volatile uint32_t hcchar;
  15415. + /** Host Channel 0 Split Control Register. <i>Offset: 500h + (chan_num * 20h) + 04h</i> */
  15416. + volatile uint32_t hcsplt;
  15417. + /** Host Channel 0 Interrupt Register. <i>Offset: 500h + (chan_num * 20h) + 08h</i> */
  15418. + volatile uint32_t hcint;
  15419. + /** Host Channel 0 Interrupt Mask Register. <i>Offset: 500h + (chan_num * 20h) + 0Ch</i> */
  15420. + volatile uint32_t hcintmsk;
  15421. + /** Host Channel 0 Transfer Size Register. <i>Offset: 500h + (chan_num * 20h) + 10h</i> */
  15422. + volatile uint32_t hctsiz;
  15423. + /** Host Channel 0 DMA Address Register. <i>Offset: 500h + (chan_num * 20h) + 14h</i> */
  15424. + volatile uint32_t hcdma;
  15425. + /** Reserved. <i>Offset: 500h + (chan_num * 20h) + 18h - 500h + (chan_num * 20h) + 1Ch</i> */
  15426. + uint32_t reserved[2];
  15427. +} dwc_otg_hc_regs_t;
  15428. +
  15429. +/**
  15430. + * This union represents the bit fields in the Host Channel Characteristics
  15431. + * Register. Read the register into the <i>d32</i> member then set/clear the
  15432. + * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
  15433. + * hcchar register.
  15434. + */
  15435. +typedef union hcchar_data
  15436. +{
  15437. + /** raw register data */
  15438. + uint32_t d32;
  15439. +
  15440. + /** register bits */
  15441. + struct {
  15442. + /** Channel enable */
  15443. + unsigned chen : 1;
  15444. + /** Channel disable */
  15445. + unsigned chdis : 1;
  15446. + /**
  15447. + * Frame to transmit periodic transaction.
  15448. + * 0: even, 1: odd
  15449. + */
  15450. + unsigned oddfrm : 1;
  15451. + /** Device address */
  15452. + unsigned devaddr : 7;
  15453. + /** Packets per frame for periodic transfers. 0 is reserved. */
  15454. + unsigned multicnt : 2;
  15455. + /** 0: Control, 1: Isoc, 2: Bulk, 3: Intr */
  15456. + unsigned eptype : 2;
  15457. + /** 0: Full/high speed device, 1: Low speed device */
  15458. + unsigned lspddev : 1;
  15459. + unsigned reserved : 1;
  15460. + /** 0: OUT, 1: IN */
  15461. + unsigned epdir : 1;
  15462. + /** Endpoint number */
  15463. + unsigned epnum : 4;
  15464. + /** Maximum packet size in bytes */
  15465. + unsigned mps : 11;
  15466. + } b;
  15467. +} hcchar_data_t;
  15468. +
  15469. +typedef union hcsplt_data
  15470. +{
  15471. + /** raw register data */
  15472. + uint32_t d32;
  15473. +
  15474. + /** register bits */
  15475. + struct {
  15476. + /** Split Enble */
  15477. + unsigned spltena : 1;
  15478. + /** Reserved */
  15479. + unsigned reserved : 14;
  15480. + /** Do Complete Split */
  15481. + unsigned compsplt : 1;
  15482. + /** Transaction Position */
  15483. +#define DWC_HCSPLIT_XACTPOS_MID 0
  15484. +#define DWC_HCSPLIT_XACTPOS_END 1
  15485. +#define DWC_HCSPLIT_XACTPOS_BEGIN 2
  15486. +#define DWC_HCSPLIT_XACTPOS_ALL 3
  15487. + unsigned xactpos : 2;
  15488. + /** Hub Address */
  15489. + unsigned hubaddr : 7;
  15490. + /** Port Address */
  15491. + unsigned prtaddr : 7;
  15492. + } b;
  15493. +} hcsplt_data_t;
  15494. +
  15495. +
  15496. +/**
  15497. + * This union represents the bit fields in the Host All Interrupt
  15498. + * Register.
  15499. + */
  15500. +typedef union hcint_data
  15501. +{
  15502. + /** raw register data */
  15503. + uint32_t d32;
  15504. + /** register bits */
  15505. + struct {
  15506. + /** Reserved */
  15507. + unsigned reserved : 21;
  15508. + /** Data Toggle Error */
  15509. + unsigned datatglerr : 1;
  15510. + /** Frame Overrun */
  15511. + unsigned frmovrun : 1;
  15512. + /** Babble Error */
  15513. + unsigned bblerr : 1;
  15514. + /** Transaction Err */
  15515. + unsigned xacterr : 1;
  15516. + /** NYET Response Received */
  15517. + unsigned nyet : 1;
  15518. + /** ACK Response Received */
  15519. + unsigned ack : 1;
  15520. + /** NAK Response Received */
  15521. + unsigned nak : 1;
  15522. + /** STALL Response Received */
  15523. + unsigned stall : 1;
  15524. + /** AHB Error */
  15525. + unsigned ahberr : 1;
  15526. + /** Channel Halted */
  15527. + unsigned chhltd : 1;
  15528. + /** Transfer Complete */
  15529. + unsigned xfercomp : 1;
  15530. + } b;
  15531. +} hcint_data_t;
  15532. +
  15533. +/**
  15534. + * This union represents the bit fields in the Host Channel Transfer Size
  15535. + * Register. Read the register into the <i>d32</i> member then set/clear the
  15536. + * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
  15537. + * hcchar register.
  15538. + */
  15539. +typedef union hctsiz_data
  15540. +{
  15541. + /** raw register data */
  15542. + uint32_t d32;
  15543. +
  15544. + /** register bits */
  15545. + struct {
  15546. + /** Do PING protocol when 1 */
  15547. + unsigned dopng : 1;
  15548. + /**
  15549. + * Packet ID for next data packet
  15550. + * 0: DATA0
  15551. + * 1: DATA2
  15552. + * 2: DATA1
  15553. + * 3: MDATA (non-Control), SETUP (Control)
  15554. + */
  15555. +#define DWC_HCTSIZ_DATA0 0
  15556. +#define DWC_HCTSIZ_DATA1 2
  15557. +#define DWC_HCTSIZ_DATA2 1
  15558. +#define DWC_HCTSIZ_MDATA 3
  15559. +#define DWC_HCTSIZ_SETUP 3
  15560. + unsigned pid : 2;
  15561. + /** Data packets to transfer */
  15562. + unsigned pktcnt : 10;
  15563. + /** Total transfer size in bytes */
  15564. + unsigned xfersize : 19;
  15565. + } b;
  15566. +} hctsiz_data_t;
  15567. +
  15568. +/**
  15569. + * This union represents the bit fields in the Host Channel Interrupt Mask
  15570. + * Register. Read the register into the <i>d32</i> member then set/clear the
  15571. + * bits using the <i>b</i>it elements. Write the <i>d32</i> member to the
  15572. + * hcintmsk register.
  15573. + */
  15574. +typedef union hcintmsk_data
  15575. +{
  15576. + /** raw register data */
  15577. + uint32_t d32;
  15578. +
  15579. + /** register bits */
  15580. + struct {
  15581. + unsigned reserved : 21;
  15582. + unsigned datatglerr : 1;
  15583. + unsigned frmovrun : 1;
  15584. + unsigned bblerr : 1;
  15585. + unsigned xacterr : 1;
  15586. + unsigned nyet : 1;
  15587. + unsigned ack : 1;
  15588. + unsigned nak : 1;
  15589. + unsigned stall : 1;
  15590. + unsigned ahberr : 1;
  15591. + unsigned chhltd : 1;
  15592. + unsigned xfercompl : 1;
  15593. + } b;
  15594. +} hcintmsk_data_t;
  15595. +
  15596. +/** OTG Host Interface Structure.
  15597. + *
  15598. + * The OTG Host Interface Structure structure contains information
  15599. + * needed to manage the DWC_otg controller acting in host mode. It
  15600. + * represents the programming view of the host-specific aspects of the
  15601. + * controller.
  15602. + */
  15603. +typedef struct dwc_otg_host_if {
  15604. + /** Host Global Registers starting at offset 400h.*/
  15605. + dwc_otg_host_global_regs_t *host_global_regs;
  15606. +#define DWC_OTG_HOST_GLOBAL_REG_OFFSET 0x400
  15607. +
  15608. + /** Host Port 0 Control and Status Register */
  15609. + volatile uint32_t *hprt0;
  15610. +#define DWC_OTG_HOST_PORT_REGS_OFFSET 0x440
  15611. +
  15612. +
  15613. + /** Host Channel Specific Registers at offsets 500h-5FCh. */
  15614. + dwc_otg_hc_regs_t *hc_regs[MAX_EPS_CHANNELS];
  15615. +#define DWC_OTG_HOST_CHAN_REGS_OFFSET 0x500
  15616. +#define DWC_OTG_CHAN_REGS_OFFSET 0x20
  15617. +
  15618. +
  15619. + /* Host configuration information */
  15620. + /** Number of Host Channels (range: 1-16) */
  15621. + uint8_t num_host_channels;
  15622. + /** Periodic EPs supported (0: no, 1: yes) */
  15623. + uint8_t perio_eps_supported;
  15624. + /** Periodic Tx FIFO Size (Only 1 host periodic Tx FIFO) */
  15625. + uint16_t perio_tx_fifo_size;
  15626. +
  15627. +} dwc_otg_host_if_t;
  15628. +
  15629. +#endif
  15630. --
  15631. 1.7.5.4